socket.io: 监听事件

socket.io: Listen for events

客户端连接到我的服务器并使用 Socket.io 发出事件,发送回数据。我只能捕捉某些事件。

此服务器端代码按预期工作:

io // an instance of SocketServer
  .on('connection', socket => {
    console.log(`Socket.io connection from ${socket.client.conn.remoteAddress}`)
    socket
      .on('start recording', ({ id }) => {  // event emitted by the client
        recordings[id] = socket
        console.log({type: 'start', id})
      })
      .on('stop recording', ({ id }) => {   // event emitted by the client
        recordings[id] = undefined
        console.log({type: 'stop', id})
      })
  })

但是,在我的端点处理程序中,我无法侦听更多事件(请注意,客户端几乎总是会加入中流,并且是与发送数据的客户端分开的客户端):

router.get('/play', (req, res, next) => {
  try {
    let id = req.query.id
    console.debug({id, recordings})
    if(!recordings[id]) {
      res.status(409)
      res.json({
        message:
          "This data source isn't currently sending data. Please check the ID or try again later.",
      })
      return
    }
    recordings[id] // this is the same socket that the code above is listening on
      .on('audio'+id, data=>{ // this event is likewise emitted by the client,
                              // but the handler never fires
        res.json({id, event:'audio', seq: data.seq})
        console.log({type:'audio event', id, seq})
      })
      .on('close'+id, () => {
        res.json({id, event:'close'})
        console.log({type:'audio close', id, seq})
      })
  } catch (e) {
    next(e)
  }
})

当我 运行 具有环境变量 DEBUG=socket* 的服务器时,我得到输出证明 Socket.io:

可以看到所有事件
Socket.io connection from ::1
  socket.io-parser decoded 2["start recording",{"id":"test_id"}] as {"type":2,"nsp":"/","data":["start recording",{"id":"test_id"}]} +18ms
  socket.io:socket got packet {"type":2,"nsp":"/","data":["start recording",{"id":"test_id"}]} +20ms
  socket.io:socket emitting event ["start recording",{"id":"test_id"}] +0ms
  socket.io:socket dispatching an event ["start recording",{"id":"test_id"}] +0ms
{
  type: 'start',
  id: 'test_id',
  recordings: {
  //  ...
}
  socket.io-parser decoded 2["audiotest_id",{"seq":0}] as {"type":2,"nsp":"/","data":["audiotest_id",{"seq":0}]} +3s
  socket.io:socket got packet {"type":2,"nsp":"/","data":["audiotest_id",{"seq":0}]} +3s
  socket.io:socket emitting event ["audiotest_id",{"seq":0}] +0ms
  socket.io:socket dispatching an event ["audiotest_id",{"seq":0}] +0ms
  socket.io-parser decoded 2["audiotest_id",{"seq":1}] as {"type":2,"nsp":"/","data":

// ...

{"type":2,"nsp":"/","data":["stop recording",{"id":"test_id"}]} +1s
  socket.io:socket got packet {"type":2,"nsp":"/","data":["stop recording",{"id":"test_id"}]} +1s
  socket.io:socket emitting event ["stop recording",{"id":"test_id"}] +0ms
  socket.io:socket dispatching an event ["stop recording",{"id":"test_id"}] +0ms
{ type: 'stop', id: 'test_id', recordings: { test_id: undefined } }
  socket.io-parser decoded 2["closetest_id"] as {"type":2,"nsp":"/","data":["closetest_id"]} +4ms
  socket.io:socket got packet {"type":2,"nsp":"/","data":["closetest_id"]} +4ms
  socket.io:socket emitting event ["closetest_id"] +0ms
  socket.io:socket dispatching an event ["closetest_id"] +0ms
  socket.io-parser decoded 1 as {"type":1,"nsp":"/"} +1ms
  socket.io:socket got packet {"type":1,"nsp":"/"} +2ms
  socket.io:socket got disconnect packet +0ms
  socket.io:socket closing socket - reason client namespace disconnect +0ms
  socket.io:client client close with reason transport close +10s

我做错了什么?

我最终解决了这个问题,方法是在套接字 connection 处理程序中侦听 'audio' 事件,然后在为此目的创建的单独 EventEmitter 实例上发出事件。然后我可以在我的 get 处理程序中收听该实例。

io
  .on('connection', socket => {
    console.log(`Socket.io connection from ${socket.client.conn.remoteAddress}`)
    socket
      // ...
      .on('audio', data => {
        // console.log({type: 'first audio event', audio: `audio ${data.id}`, data})
        emitter.emit(`audio ${data.id}`, data)
      })
      .on('close', ({id}) => emitter.emit(`close ${id}`))
  })

然后:

      emitter
        .on(`audio ${id}`, data => {
          if(!mimeType) {
            mimeType = data.mimeType
            res.writeHead(200, {'Content-Type': mimeType})
          }
          res.write(data.data)
          console.debug({event: `audio ${id}`, seq: data.seq, mimeType, length: data.data.length})
        })
        .on(`close ${id}`, () => {
          console.debug({type:'audio close', id})
          res.end()
        })