Sharedworker 使用 EventSource 连接到我的 expressjs 服务器。
//worker.js
const startSSE = () => {
const sse = new EventSource(`/events`, {withCredentials: true})
sse.addEventListener('open', e => console.log('open'))
sse.addEventListener('ping', e => console.log('ping'))
return sse
}
let sse = startSSE()
setInterval(() => {
if (sse.readyState !== 1) {
sse = startSSE()
}
}, 1000)
带有 expressjs 的服务器,将所有连接存储到数组
clients
.
// sseClientsManager.js
let clients = []
const
connectClient = (req, res, next) => {
if (req.headers.accept == 'text/event-stream') {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': process.env.API_HOST,
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'
})
if (clients.filter(client => client.sid === req.cookies.rnd).length === 0) {
clients.push({sid: req.cookies.rnd, con: res})
}
} else {
next()
}
},
sendSSE = (res, event = 'message', msg = null) => {
res.write('event: ' + event + '\n')
res.write('id: ' + Date.now() + '\n')
res.write('data: ' + msg + '\n\n')
},
sseClientsManager = () => (req, res, next) => connectClient(req, res, next)
setInterval(() => clients.map(client => sendSSE(client.con, 'ping')), 20000)
setInterval(() => clients = clients.filter(client => !(client.con.stream.closed && client.con.stream.destroyed)), 1000)
module.exports = sseClientsManager
客户端在刷新页面时生成一个新的
rnd
,然后服务器在clients
数组中创建一个新元素,但旧条目仍然存在。事实证明,一个用户只需按 F5 即可创建任意数量的服务器活动连接