Server-Sent Events 协议,实现服务端长连接传数据
介绍
Server-Sent Events (SSE) 是一种服务器向浏览器单向发送事件通知的技术,这种方法允许服务器在有新事件时实时地将更新推送到客户端,而不需要客户端轮询服务器以获取更新。SSE 是建立在 HTTP 协议之上的,因此它使用简单的 HTTP GET 请求与服务器建立连接。
主要特征
- 单向通信:只能由服务器向客户端推送消息,客户端不能通过这个连接发送消息给服务器。
- 基于文本:SSE 传输的数据是基于文本的,通常是 UTF-8 编码的。
- 重连机制:如果连接被关闭,浏览器会自动尝试重新连接。
- 事件标识:服务器可以为发送的事件指定事件类型和ID,客户端可以根据这些信息进行相应的处理。
使用场景
- 实时通知
- 聊天应用
- 股票或其它实时数据的更新
优点
- 简单易用,使用标准的HTTP协议。
- 兼容性良好,大部分现代浏览器都支持SSE。
- 内置自动重连机制。
缺点
- 只支持文本数据,不可直接发送二进制数据。
- 只能实现服务器到客户端的单向通讯。
后端接口
- C#
[HttpGet, AllowAnonymous]
public async IAsyncEnumerable<string> GetDataStream()
{
var dataItems = new List<string> { "Item1", "Item2", "Item3", "Item4", "Item5" };
foreach (var item in dataItems)
{
//使用迭代器返回数据项
yield return item;
//模拟数据生成的延时
await Task.Delay(1000);
}
}
[HttpGet, AllowAnonymous]
public async Task GetDataStream(CancellationToken cancellationToken)
{
var response = Response;
response.Headers.Add("X-Accel-Buffering", "no");//取消Nginx缓存
response.Headers.Add("Content-Type", "text/event-stream");
response.Headers.Add("Cache-Control", "no-cache");
for (int i = 0; i < 10; i++)
{
//如果客户端断开连接,则退出循环
if (cancellationToken.IsCancellationRequested) break;
//模拟实时返回数据项
await response.WriteAsync($"data: Message {i}\n\n");
await response.Body.FlushAsync();
//模拟数据生成的延时
await Task.Delay(1000);
}
}
- PHP
<?php
//ini_set('display_errors', 1);
//error_reporting(E_ALL);
//设置头部 SSE 应答
header('X-Accel-Buffering: no'); //取消Nginx缓存
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
//函数,生成SSE数据格式
function sendMsg($data) {
echo "id: ". time() . PHP_EOL;
echo "data: $data" . PHP_EOL.PHP_EOL;
ob_flush();
flush();
}
//发送数据
while (true) {
$data = date("h:i:s", time());
if (isset($_REQUEST["data"])) $data = $data . "_" .$_REQUEST["data"];
//发送数据
sendMsg($data);
//休眠1秒
sleep(1);
}
前端调用
- JavaScript
if (!!window.EventSource) {
var source = new EventSource('/GetDataStream');
source.onmessage = function(event) {
console.log(event.data);
};
source.onerror = function(error) {
console.error("SSE 出现错误:", error);
};
} else {
console.log("浏览器不支持 SSE");
}
版权属于:zgcwkj
本文链接:https://blog.zgcwkj.cn/archives/226.html
转载声明:请注明本文章的标题及内容的出处和声明,谢谢
评论已关闭