跳到主要内容
版本:4.0

HttpSse功能

1. 概述

Server-Sent Events (SSE) 是HTML5中引入的一种服务器推送技术,允许服务器主动向客户端推送数据。与WebSocket不同,SSE是单向通信,只能由服务器向客户端推送消息,但它基于HTTP协议,实现更简单,且能自动重连。

TouchSocket的Http组件完整支持SSE功能,提供了简洁易用的API来实现服务器端推送和客户端接收。

1.1 SSE的特点

  • 单向通信:服务器到客户端的单向数据流
  • 基于HTTP:使用标准HTTP协议,不需要特殊的握手过程
  • 自动重连:浏览器会自动处理断线重连
  • 文本协议:传输的数据格式为文本(通常是UTF-8编码)
  • 事件流:支持事件ID、事件类型和重连间隔等元数据

1.2 适用场景

  • 实时消息推送(如新闻、通知)
  • 股票行情更新
  • 服务器状态监控
  • 进度通知
  • 日志实时展示

2. 服务器端实现

2.1 创建SSE服务器

在TouchSocket中实现SSE服务器非常简单,只需创建一个Http服务器并添加SSE插件即可。

🔄 正在加载代码...

服务器端的关键点:

  1. 创建HttpService实例
  2. 在插件配置中添加自定义的SSE插件
  3. 启动服务器监听指定端口

2.2 发送SSE消息

在插件中处理SSE请求,通过CreateSseWriter方法创建SSE写入器,然后发送消息。

🔄 正在加载代码...

发送SSE消息的关键步骤:

  1. 检查请求路径:判断请求是否是SSE路径
  2. 设置响应状态:调用SetStatusWithSuccess()设置正确的响应码和Content-Type
  3. 创建SSE写入器:通过response.CreateSseWriter()创建SSE写入器
  4. 构建SSE消息:创建SseMessage对象,设置消息内容、事件ID、重连间隔等
  5. 发送消息:调用await sseWriter.WriteAsync(sseItem)发送消息
  6. 完成流:发送完毕后调用await sseWriter.CompleteAsync()关闭SSE流

2.3 SseMessage属性说明

SseMessage类包含以下属性:

  • Data:消息数据内容(字符串)
  • EventId:事件ID,客户端可用于断线重连时的Last-Event-ID
  • EventType:事件类型,客户端可根据不同类型处理不同的消息
  • ReconnectionInterval:重连间隔时间,告诉客户端断线后多久重连

3. 客户端实现

3.1 使用TouchSocket客户端接收SSE

TouchSocket的HttpClient提供了完整的SSE客户端支持,可以方便地接收服务器推送的消息。

🔄 正在加载代码...

客户端接收SSE的关键步骤:

  1. 创建HttpClient:实例化HttpClient并连接到服务器
  2. 构建请求:创建GET请求,设置SSE路径
  3. 发送请求:使用await client.RequestAsync()发送请求
  4. 创建SSE阅读器:通过response.CreateSseReader()创建SSE阅读器
  5. 循环接收消息:使用await foreach异步循环读取所有SSE消息
  6. 处理消息:在循环中处理每条接收到的消息

3.2 浏览器客户端

除了使用TouchSocket的HttpClient,也可以使用浏览器的原生EventSource API:

const eventSource = new EventSource('http://localhost:7789/sse');

eventSource.onmessage = function(event) {
console.log('收到消息:', event.data);
};

eventSource.addEventListener('custom-event', function(event) {
console.log('自定义事件:', event.data);
});

eventSource.onerror = function(error) {
console.error('SSE错误:', error);
};

4. 最佳实践

4.1 超时控制

在实际应用中,建议设置合理的超时时间,避免长时间占用连接:

using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5));
using var responseResult = await client.RequestAsync(httpRequest, cancellationTokenSource.Token);

4.2 心跳机制

对于长时间的SSE连接,建议定期发送心跳消息,防止连接被中间代理关闭:

var sseWriter = response.CreateSseWriter();
while (!cancellationToken.IsCancellationRequested)
{
// 发送数据或心跳
await sseWriter.WriteAsync(new SseMessage { Data = "heartbeat" });
await Task.Delay(TimeSpan.FromSeconds(30), cancellationToken);
}

4.3 错误处理

客户端应正确处理可能的异常情况:

try
{
await foreach (var sse in sseReader.ReadAllAsync(cancellationToken))
{
// 处理消息
}
}
catch (OperationCanceledException)
{
// 超时或取消
}
catch (Exception ex)
{
// 其他错误
Console.WriteLine($"SSE错误: {ex.Message}");
}

5. 示例代码

完整的SSE示例代码请参考:

6. 注意事项

  1. 单向通信:SSE只支持服务器到客户端的单向推送,如需双向通信请使用WebSocket
  2. 文本格式:SSE只能传输文本数据,如需传输二进制数据需要进行编码(如Base64)
  3. 连接数限制:浏览器对同一域名的SSE连接数有限制(通常为6个)
  4. 跨域问题:如需跨域访问,服务器需要正确设置CORS头部
  5. 代理兼容性:某些代理服务器可能会缓冲SSE响应,影响实时性

7. 总结

TouchSocket提供了完善的SSE支持,无论是服务器端还是客户端都提供了简洁易用的API。通过CreateSseWriterCreateSseReader,您可以轻松实现服务器推送功能,满足实时消息推送的需求。