2.13Server-Sent Events 单向通信
随着人工智能聊天机器人 ChatGPT 的快速流行,其用户界面中模拟打字机效果的对话设计给人留下了深刻印象。这种生动逼真的交互体验,实际上是通过一种称为“服务器发送事件”(Server-Sent Events, SSE)的技术实现的。
随着人工智能聊天机器人 ChatGPT 的快速流行,其用户界面中模拟打字机效果的对话设计给人留下了深刻印象。这种生动逼真的交互体验,实际上是通过一种称为“服务器发送事件”(Server-Sent Events, SSE)的技术实现的。
Server-Sent Events 是一种允许服务器主动向客户端(通常是浏览器)发送实时更新数据的通信技术。与传统的客户端请求-服务器响应模式不同,SSE 实现了服务器到客户端的单向、异步通信,从而无需客户端不断轮询服务器以获取最新数据。 这种技术极大地减轻了服务器的负担,并提高了数据传输的效率和实时性。
Server-Sent Events 的应用场景:
- 实时通知:可以用来实现实时的消息提醒或通知系统,如社交网络上的新消息提示或邮件到达通知。
- 数据流更新:对于需要持续更新的数据,如股票价格、天气信息或体育比赛结果,
SSE能够提供即时的数据更新。 - 进度报告:在执行耗时较长的任务时,比如文件上传或复杂计算过程中,
SSE可以用来向客户端报告任务的进度。 - 日志和监控:在开发和运维领域,
SSE可用于实时显示日志文件的变化或监控系统的健康状态。
以下示例展示了如何使用 Server-Sent Events 向服务器获取数据:
await httpRemoteService.ServerSentEventsAsync("https://localhost:7044/HttpRemote/Events" // 接收到数据时的操作 , async (data, token) => { Console.WriteLine(data.Data); await Task.CompletedTask; }, cancellationToken: cancellationToken);// 使用构建器模式await httpRemoteService.SendAsync(HttpRequestBuilder .ServerSentEvents("https://localhost:7044/HttpRemote/Events" // 接收到数据时的操作 , async (data, token) => { Console.WriteLine(data.Data); await Task.CompletedTask; }), cancellationToken: cancellationToken);Server-Sent Events 也支持以 IAsyncEnumerable<ServerSentEventsData> 的方式消费数据,让你可以使用 await foreach 来迭代每个轮询响应:
await foreach (var data in httpRemoteService.ServerSentEventsAsAsyncEnumerable("https://localhost:7044/HttpRemote/Events", cancellationToken: cancellationToken)){ Console.WriteLine(data.Data);}// 使用构建器模式await foreach (var data in httpRemoteService.SendAsAsyncEnumerable(HttpRequestBuilder.ServerSentEvents("https://localhost:7044/HttpRemote/Events"), cancellationToken)){ Console.WriteLine(data.Data);}data 参数的类型为 ServerSentEventsData,包含以下属性:
- 属性:
Event:事件类型(string类型)。Data:消息(string类型)。RawLine:原始消息行(string类型)。Id:事件ID(string类型)。Retry:重新连接的时间(以毫秒为单位的int类型)。CustomFields:自定义的字段数据(IReadOnlyCollection<KeyValuePair<string, string>>类型)。
您还可以监听连接成功和发送异常时的事件:
await httpRemoteService.ServerSentEventsAsync("https://localhost:7044/HttpRemote/Events" // 接收到数据时的操作 , async (data, token) => { Console.WriteLine(data.Data); await Task.CompletedTask; }, builder => builder // 连接打开时操作 .SetOnOpen(() => { Console.WriteLine("连接成功。"); }) // 连接未打开时操作 .SetOnError((ex) => { Console.WriteLine("连接错误。" + ex.Message); }), cancellationToken: cancellationToken);// 使用构建器模式await httpRemoteService.SendAsync(HttpRequestBuilder .ServerSentEvents("https://localhost:7044/HttpRemote/Events" // 接收到数据时的操作 , async (data, token) => { Console.WriteLine(data.Data); await Task.CompletedTask; }) // 连接打开时操作 .SetOnOpen(() => { Console.WriteLine("连接成功。"); }) // 连接未打开时操作 .SetOnError((ex) => { Console.WriteLine("连接错误。" + ex.Message); }), cancellationToken: cancellationToken);Server-Sent Events 特别适合那些需要服务器向客户端发送更新,但客户端不需要频繁向服务器发送请求的应用场景。无论是用于实时更新数据、提供进度报告还是实现简单的通知系统,SSE 都是一个值得考虑的选择。