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插件即可。
🔄 正在加载代码...
服务器端的关键点:
- 创建
HttpService实例 - 在插件配置中添加自定义的SSE插件
- 启动服务器监听指定端口
2.2 发送SSE消息
在插件中处理SSE请求,通过CreateSseWriter方法创建SSE写入器,然后发送消息。
🔄 正在加载代码...
发送SSE消息的关键步骤:
- 检查请求路径:判断请求是否是SSE路径
- 设置响应状态:调用
SetStatusWithSuccess()设置正确的响应码和Content-Type - 创建SSE写入器:通过
response.CreateSseWriter()创建SSE写入器 - 构建SSE消息:创建
SseMessage对象,设置消息内容、事件ID、重连间隔等 - 发送消息:调用
await sseWriter.WriteAsync(sseItem)发送消息 - 完成流:发送完毕后调用
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的关键步骤:
- 创建HttpClient:实例化
HttpClient并连接到服务器 - 构建请求:创建GET请求,设置SSE路径
- 发送请求:使用
await client.RequestAsync()发送请求 - 创建SSE阅读器:通过
response.CreateSseReader()创建SSE阅读器 - 循环接收消息:使用
await foreach异步循环读取所有SSE消息 - 处理消息:在循环中处理每条接收到的消息
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. 注意事项
- 单向通信:SSE只支持服务器到客户端的单向推送,如需双向通信请使用WebSocket
- 文本格式:SSE只能传输文本数据,如需传输二进制数据需要进行编码(如Base64)
- 连接数限制:浏览器对同一域名的SSE连接数有限制(通常为6个)
- 跨域问题:如需跨域访问,服务器需要正确设置CORS头部
- 代理兼容性:某些代理服务器可能会缓冲SSE响应,影响实时性
7. 总结
TouchSocket提供了完善的SSE支持,无论是服务器端还是客户端都提供了简洁易用的API。通过CreateSseWriter和CreateSseReader,您可以轻松实现服务器推送功能,满足实时消息推送的需求。