大多数时候,网页必须向服务器发送请求以接收新数据。服务端发送的事件,能够将消息推送到网页
本质上,SSE使用户能够订阅实时数据流。 每当此数据流更新时,用户均可以实时看到新事件。 若是你知道Long-Polling或Web Socket那么你可能以为它没什么大不了
Websocket是服务器之间的双向通讯形式。 它一般用于创建聊天室或多人视频游戏,由于这些应用程序场景须要服务器和客户端之间的持续通讯。 你能够将SSE视为单向websocket。只有服务器能够将消息发送到订阅的客户端。在许多Web应用程序中,Web套接字可能会过大。 例如,商品的价格不须要双向通讯。服务器仅须要单向通讯来更新其全部客户端的价格。 可是在客户端与服务端须要强交互的场景下,Web Socket还是最佳选择
长轮询是一种通讯方法,客户端按期访问服务器获取新数据。 适用于须要通过必定时间的计算或者人工干预的响应 SSE一般用于快速生成事件的应用程序中,即时更新。 长轮训虽然能够避免短轮训形成的服务端过载,但在服务端返回数据后仍须要客户端主动发起下一个长轮训请求,等待服务端响应
1.SSE是单向的git
消息数据是从服务器到客户端,单向传递
2.若是不使用HTTP/2会受到最大打开链接数的限制web
浏览器对每一个域名限制的http链接数为6,这是跨标签的。HTTP/2默认值是100
浏览器EventSource实例将建立一个持久的HTTP链接,直到经过调用关闭eventSource.close()。
const es = new EventSource('/v1/index/es') es.onopen = () => { console.log('es open') } es.onerror = (err) => { console.log('err', err) } es.addEventListener('test', (res) => { const { data } = res console.log('来自服端消息:', data) })
发送事件须要使用text/event-stream类型。每一个消息均以文本块形式发送,并以一对换行符结尾。
1.格式 每条收到的消息都有如下字段的组合浏览器
event 标识所描述事件类型的字符串 若是指定了 在浏览器上将触发指定的侦听器 addEventListener()用于侦听命名事件。 onmessage则处理未指定事件名称的消息。 data 消息的数据字段 id 事件ID retry 尝试发送事件时要使用的从新链接时间 必须是整数,以毫秒为单位
const { Readable } = require('stream') // 写入数据 const send = (stream, event, data) => { return stream.push(`event:${event}\ndata: ${JSON.stringify(data)}\n\n`) } router.all('/es', async (ctx) => { // 建立流 const reader = new Readable() reader._read = function (data) { console.log('>') } ctx.set({ 'Content-Type': 'text/event-stream', // 响应格式 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }) send(reader, 'test', { data: 111 }) ctx.body = reader let count = 1 // 模拟消息发送 const timer = setInterval(() => { send(reader, 'test', { data: 111, count: count++ }) }, 3000) // 处理链接断开 ctx.req.on('close', () => { console.log('close') clearInterval(timer) reader.destroy() }) })
https://gitee.com/wjj0720/ser...