在 expressjs 中获取活动事件源连接的有效列表

问题描述 投票:0回答:0

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

即可创建任意数量的服务器活动连接
express server-sent-events shared-worker
© www.soinside.com 2019 - 2024. All rights reserved.