socketio / socket.io-mongo-adapter

The Socket.IO MongoDB adapter, allowing to broadcast events between several Socket.IO servers
https://socket.io
MIT License
24 stars 7 forks source link

Connection state recovery not working #20

Closed bohdankovt closed 1 day ago

bohdankovt commented 8 months ago

Connection state recovery not working

2024-01-09T09:58:05.987Z socket.io-mongo-adapter restoring session: Aqp6Uis0930quMDiAAAF
2024-01-09T09:58:05.991306129Z 2024-01-09T09:58:05.991Z socket.io:namespace error while restoring session: session or offset not found

mongo 5.0 mongodb: 6.3.0 socket.io: 4.6.1 socket.io-mongo-adapter: 0.3.0

client:

export const socketIo = io(URL, {
    path: '/websocket',
    autoConnect: false,
    transports: ['websocket', 'polling'],
    withCredentials: true,
});

server:

export const server = createServer();
export const socketIo = new Server(server, {
    cors: {
        origin: websocket.cors,
        credentials: true,
    },
    connectionStateRecovery: {
        maxDisconnectionDuration: 30 * 1000,
    },
});

createAdapter().then(a => socketIo.adapter(a));

createAdapter:

import { MongoClient } from 'mongodb';
import { createAdapter as createMongoAdapter } from '@socket.io/mongo-adapter';
import logger from '../logger';

const DB = 'mydb';
const COLLECTION = 'socket.io-adapter-events';

const mongoClient = new MongoClient('mongodb://mongodb:27017/?replicaSet=rs0&directConnection=true');

const configureMongoEvents = client => {
    client.on('open', () => logger.info('[mongodb]: Connection is established to the Mongo DB server'));
    client.on('error', err => logger.error(`[mongodb]: ${err}`));
    client.on('close', () => logger.info('[mongodb]: Connection has closed'));
};

configureMongoEvents(mongoClient);

export const createAdapter = async () => {
    await mongoClient.connect();
    const mongoCollection = mongoClient.db(DB).collection(COLLECTION);

    await mongoCollection.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3500, background: true });

    return createMongoAdapter(mongoCollection, { addCreatedAtField: true });
};
darrachequesne commented 8 months ago

Hi! I think that's because you need to send at least one packet to the client, in order to initialize the offset. I will make it clearer in the documentation.

Edit: or it might be related to https://github.com/socketio/socket.io-mongo-adapter/commit/1a0488562f1e8b4171af20378aacfa43072980dd. Let me publish a new version with the fix.

darrachequesne commented 8 months ago

Could you please check with version 0.3.1?

bohdankovt commented 8 months ago

In my tests server always send at least one packet to client.

Seems problem with version of node mongodb driver. I tried to setup adapter with mongo version 5 and mongodb driver version 6.3.0 (latest), but it was not worked. After that i tried to downgrade mongodb driver to version 5.0 but it was not worked too. Only on mongodb driver version 4 it worked correctly.

Also i forked your repo and tried to run your tests with debug. I saw that all tests for connection state recovery mechanizm are passed but when i enable debug mode i saw that adapter logs to console error on recovering steps. It seems tests not working as expected.

I think you should add compatability table to readme file for supported mongo versions and mongodb driver.

darrachequesne commented 7 months ago

I think this should be fixed by https://github.com/socketio/socket.io-mongo-adapter/commit/d3fa03874038ed9ec011d8795ac7dc6d840f4abe, included in version 0.3.2. Could you please check?

dmitrysl commented 1 week ago

The fix works, so issue can be closed. Thanks.