socketio / socket.io-admin-ui

Admin UI for Socket.IO
https://admin.socket.io
MIT License
358 stars 95 forks source link

Error serialising sockets with session stores #7

Closed liemnotliam closed 3 years ago

liemnotliam commented 3 years ago

I have an application that shares an express session with socket.io. The session is backed by a redis store. The admin runs fine when the socket.io server starts but crashes when a client connects to the socket.io server.

../app/node_modules/notepack.io/lib/encode.js:256
      throw new Error('Could not encode');
      ^

Error: Could not encode
    at _encode (../app/node_modules/notepack.io/lib/encode.js:256:13)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:162:19)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:162:19)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:246:17)
    at _encode (../app/node_modules/notepack.io/lib/encode.js:162:19)
    at Object.encode (../app/node_modules/notepack.io/lib/encode.js:261:41)
    at RedisAdapter.broadcast (../app/node_modules/socket.io-redis/dist/index.js:313:33)
    at BroadcastOperator.emit (../app/node_modules/socket.io/dist/broadcast-operator.js:113:22)
    at Namespace.emit (../app/node_modules/socket.io/dist/namespace.js:168:73)
    at Namespace.<anonymous> (../app/node_modules/@socket.io/admin-ui/dist/index.js:231:24)
    at Namespace.emit (events.js:315:20)

From what I gathered, the crash happens because the socket serialisation in https://github.com/socketio/socket.io-admin-ui/blob/f45342266245fe3fa0049ea7ba556a9e071b056f/lib/index.ts#L349 contains redis related things in socket.handshake:

{
...
sessionStore: RedisStore {
     _events: [Object: null prototype] {
       disconnect: [Function: ondisconnect],
       connect: [Function: onconnect]
     },
     _eventsCount: 2,
     _maxListeners: undefined,
     prefix: 'sess:',
     scanCount: 100,
     serializer: Object [JSON] {},
     client: RedisClient {
...
}

I'm not quite sure where that sessionStore is added to socket.handshake but maybe socket.io-admin could filter the handshake object based on its interface in https://github.com/socketio/socket.io/blob/b84ed1e41c9053792caf58974c5de9395bfd509f/lib/socket.ts#L64?

darrachequesne commented 3 years ago

maybe socket.io-admin could filter the handshake object based on its interface

Sounds good to me. Would you have time to open a PR for this?

liemnotliam commented 3 years ago

Haven't done a lot of TypeScript but there doesn't seem to be a nice way to get the interface keys without hardcoding them, any thoughts or suggestions?

TS playground link image

darrachequesne commented 3 years ago

I think the easiest way would indeed be to hardcode them, which is fine in this case I think.

darrachequesne commented 3 years ago

This should be fixed by https://github.com/socketio/socket.io-admin-ui/commit/1cf991e49a1e2b172acca40ca3d259dad9c22915, included in version 0.1.2.