【AI落地工程技术】-SSE协议
目录
(图片来源网络,侵删)
SSE协议内容
SSE事件格式
使用示例
示例一
客户端(JavaScript)
服务器端(Node.js 示例)
示例二
前端(JavaScript)
后端(Java,使用Spring Boot和Servlet API)
SSE(Server-Sent Events)协议是一种用于服务器主动向客户端推送数据的技术,也称为“事件流”(Event Stream)。它基于HTTP协议,利用长连接特性,在客户端与服务器之间建立一条持久化连接,并通过这条连接实现服务器向客户端的实时数据推送。ChatGPT即采用的是SSE协议。
SSE协议内容
- 协议头:
- SSE协议返回的是事件流,需要指定内容类型。因此,在HTTP header里需要加上以下信息:
- Content-Type: text/event-stream
- Connection: keep-alive
- Cache-Control: no-cache
- SSE协议返回的是事件流,需要指定内容类型。因此,在HTTP header里需要加上以下信息:
- 协议内容:
- 协议内容放在HTTP返回的body里,每次返回一个Event信息。
- 每个Event里可以包含以下5个属性(但并非所有属性都是必需的):
- id:用于表示Event的序号,客户端通过序号实现断线重连功能。
- event:表示自定义事件类型,客户端通过该字段区分不同消息。
- data:表示返回的业务数据,如果数据很长可以分成多行返回。
- retry:(可选)注释消息,表示重新连接的时间间隔(单位:毫秒)。
- 每个属性值占用一行,每行的内容都是由属性名称+属性值组成+换行符,之间用冒号隔开(:)。
- 两个消息之间用额外的换行符(\n\n)区分。
SSE事件格式
每个SSE事件都以文本形式发送,遵循以下格式:
- 单行注释:以: 开头(例如 : 这是一条注释\n)
- 字段:由字段名、冒号、字段值以及一个换行符组成(例如 data: This is a message\n)
- 事件:通过event字段指定(例如 event: myevent\n)
- ID:通过id字段指定,用于在重新连接时帮助客户端确定错过的消息(例如 id: 123\n)
- 重试:通过retry字段指定在重新连接之前的延迟时间(单位:毫秒)(例如 retry: 2000\n)
- 消息结束:两个换行符(\n\n)表示一个事件的结束和下一个事件的开始
使用示例
示例一
客户端(JavaScript)
// 创建EventSource对象 const eventSource = new EventSource('http://example.com/sse'); // 监听服务器发送的事件 eventSource.onmessage = function(event) { console.log('收到消息:', event.data); }; // 监听服务器关闭连接的事件 eventSource.onclose = function() { console.log('连接已关闭'); }; // 监听服务器错误事件 eventSource.onerror = function() { console.log('连接出错'); };
服务器端(Node.js 示例)const http = require('http'); const server = http.createServer((req, res) => { if (req.url === '/sse' && req.method === 'GET') { // 设置响应头 res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Connection': 'keep-alive', 'Cache-Control': 'no-cache' }); // 模拟发送数据 let count = 0; const interval = setInterval(() => { const eventData = `data: 这是第 ${count++} 条消息\n\n`; res.write(eventData); // 假设在发送10条消息后关闭连接 if (count > 10) { clearInterval(interval); res.end(); } }, 1000); // 每秒发送一次 } }); server.listen(8080, () => { console.log('SSE 服务器已启动,监听 8080 端口'); });在上面的示例中,客户端使用EventSource对象创建一个与服务器端的SSE连接,并监听不同的事件。服务器端则创建一个HTTP服务器,并在接收到特定的GET请求时,通过长连接向客户端发送数据。这个示例模拟了一个简单的SSE服务器,每秒钟向客户端发送一条消息,并在发送了10条消息后关闭连接。
示例二
前端(JavaScript)
// 创建EventSource实例并连接到SSE服务 var source = new EventSource('/server-sent-events-endpoint'); // 监听message事件(默认事件类型) source.onmessage = function(event) { console.log('Received data:', event.data); }; // 监听自定义事件类型 source.onmyevent = function(event) { console.log('Received myevent:', event.data); }; // 监听连接打开事件 source.onopen = function(event) { console.log('Connection to server opened.'); }; // 监听连接错误事件 source.onerror = function(event) { if (source.readyState === EventSource.CLOSED) { // 连接已关闭,可以尝试重新连接 console.log('Connection to server was closed.'); } };后端(Java,使用Spring Boot和Servlet API)
在Spring Boot应用中,你可以使用@RestController和@GetMapping来创建一个SSE端点,但更常见的是使用ServletResponse直接发送SSE消息。
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/server-sent-events-endpoint") public class SseServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/event-stream"); resp.setCharacterEncoding("UTF-8"); PrintWriter out = resp.getWriter(); int count = 0; while (true) { // 模拟持续发送事件 out.println("data: Event " + (count++) + " at " + System.currentTimeMillis()); out.println("event: server-time"); // 可选的事件类型 out.println("retry: 1000\n"); // 推荐客户端在断开连接后等待1秒再重连 // 刷新输出流 out.flush(); // 暂停一段时间再发送下一条消息 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); break; } } // 注意:在实际应用中,你可能需要一种机制来优雅地关闭连接,而不是使用无限循环 } }在这个示例中,我们创建了一个Servlet来模拟SSE服务。Servlet响应设置了正确的内容类型和字符编码,并使用PrintWriter发送SSE事件。在实际应用中,你可能会使用一个更复杂的逻辑来控制何时发送消息以及如何优雅
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!
