EventSource
概念
SSE(Server-sent events)服务器发送事件,主要是客户端用到 EventSource
API
EventSource
是兼容性比 WebSocket
更好的浏览器API
与 WebSocket 不同的是,EventSource 是单向的。数据只能从服务端到发送到客户端
Node.js 服务端
实现EventSource连接就是,服务器向客户端声明,接下来要发送的是流信息(streaming)
也就是说,发送的不是一次性的数据包,而是一个数据流,会连续不断地发送过来。
客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放就是这样的例子。
本质上,这种通信就是以流信息的方式,完成一次用时很长的下载。
服务端按如下响应,就能满足与客户端建立EventSource连接
js
response.writeHead(200, {
"Content-Type":"text/event-stream",
"Cache-Control":"no-cache",
"Connection":"keep-alive",
"Access-Control-Allow-Origin": '*',
});
response.write(`retry: 10000\n`)
response.write(`
id: test
event: custom-event
data: ${new Date()}\n
`)
// event-stream 连接会保持,每次写入的数据会被客户端接收
事件流格式规范
4个有效字段,其他会被忽略
retry
:设置连接断开后,客户端自动重连的时间间隔。设置非整数无效id
:事件 ID,客户端通过lastEventId
读取event
:事件类型,默认为message
data
:事件的数据字段
消息与消息间通过空行区分,没有空行会合并消息
js
`
data: {
data: "foo": "bar",
data: "baz", 555
data: }
`
// { "foo": "bar", "baz", 555 }
客户端
浏览器提供全局API EventSource
构造函数方便建立连接
js
const evtSource = new EventSource("http://localhost:9000")
console.log(evtSource.readyState); // 0
evtSource.addEventListener('open', function(){
console.log(evtSource.readyState); // 1
})
evtSource.addEventListener('message', function(event){
console.log(event.data) //没有 `event` 或 `event: message` 消息会在这里接收
})
evtSource.addEventListener('custom-event', function(){
console.log(event.data) //`event: custom-event` 消息会在这里接收
console.log(event.lastEventId) // 'test'
})
evtSource.addEventListener('error', function(){
evtSource.close() // 关闭连接,不关闭会自动重连
console.log(evtSource.readyState); // 2
})