EventSource VS WebSocket
EventSource
定义
EventSource也称为SSE(Server-Sent Events),是服务器推送的一个网络事件接口,一个EventSource会对http服务开启一个持久化链接,它发送的事件格式是‘text/stream’,开启EventSource事件后,它会一直保持开启状态,直到被要求关闭
Server使用
我采用的是node + Koa的方式,由于它是属于http的请求方式,所以通过路由匹配,主要需要设置{'Content-Type': 'text/event-stream'}形式
const app = new Koa();
app.use(async (ctx, next) => {
if (ctx.path === '/stream') {
ctx.request.socket.setTimeout(0)
ctx.req.socket.setNoDelay(true)
ctx.req.socket.setKeepAlive(true)
ctx.set({
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': 'true'
})
const stream = new PassThrough()
ctx.status = 200
ctx.body = stream
setInterval(() => {
stream.write(`data: ${new Date()}\n\n`)
}, 1000)
return
}
try {
await next()
}
})
client使用
初始化事件对象, EventSource第一个参数是访问的http的url, 第二个config主要配置跨域属性, 3000是客户端端口,通过proxy代理到后端
let serverEvent = new EventSource('http://localhost:3000/stream', {
withCredentials: true
})
相关的事件监听方法
serverEvent.onopen = (event) => {
console.log(event, 'onopen----event00000')
}
// 连接成功,消息推送
serverEvent.onmessage = (event) => {
console.log(event, 'onmessage----event00000')
}
// 服务发生异常,譬如跨域问题等
serverEvent.onerror = (event) => {
console.log(event, 'onerror----event00000')
}
由于它在http下,所以你在network中可以找到对应的api,在里面有EventStream就是对应的返回结果,如果报错可以通过查看返回的status等信息排查问题原因
WebSocket
定义
WebSocket可以在用户的浏览器和服务器之间打开交互的通信方式,使用此API,您可以向服务器发送消息并接受事件驱动的响应,而无需通过轮训服务器的方式获得相应。
server使用
在server端,新建目录文件wss/websocket.js, 其内容如下, 其中WebSocket.Server的第一个参数是后端开启的server服务,path对应的是websocket的路径,不填写默认是'/',我这里采用的ws的库,另外还有像socket.io等库
const WebSocket = require('ws')
class ws {
static ws = WebSocket.Server // 默认实例
static init (server) {
// 创建实例
// eslint-disable-next-line new-cap
console.log('this.init, this.init, this.init, ')
this.ws = new WebSocket.Server({ server, path: '/websocket' })
this.ws.on('connection', async (ws, request) => {
let count = 0
this.ws.clients.forEach(client => {
setInterval(() => {
const data = {
id: count,
firstName: `first-${count}`
}
client.send(JSON.stringify(data))
count++
}, 2000)
})
this.ws.send('connected')
})
}
}
module.exports = ws
client使用
这里WebSocket后面添加的是ws对应的url,其中3000是客户端端口,websocket对应的路径同server端WebSocket.Server第二个参数path对应。
const exampleSocket = new WebSocket(
"ws://localhost:3000/websocket"
);
exampleSocket.onmessage = (event) => {
const data = JSON.parse(event.data)
if (data?.id >= 3) {
exampleSocket.close();
}
}
需要注意的是,这里如果需要访问proxy到服务端,通过vite/webpack相关配置里需要加{ws: true}的属性,如下图所示
另外,它的数据查看方式是在network下的ws中查看
对比
EventSource | WebSocket |
---|---|
单向传输(server 到 client) | 双向传输 |
基于http协议 | 基于tcp协议 |
只支持文本(utf-8) | 支持二进制/文本(utf-8)格式数据传输 |
浏览器限制传输个数(chrome 限制6个,因为是http请求,http1.0有限制) | 浏览器不限制 |
轻量级协议,实现简单 | 重量级协议,实现复杂 |
支持断开重连 | 需要额外部署 |
不支持跨域,需要设置header | 支持跨域 |
没有防火墙阻塞 | 有防火墙 |
转载自:https://juejin.cn/post/7222897190699565116