socket.io-mongo-adapter icon indicating copy to clipboard operation
socket.io-mongo-adapter copied to clipboard

Connection state recovery not working

Open bohdankovt opened this issue 2 years ago • 4 comments

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 });
};

bohdankovt avatar Jan 09 '24 10:01 bohdankovt

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 avatar Jan 10 '24 14:01 darrachequesne

Could you please check with version 0.3.1?

darrachequesne avatar Jan 10 '24 15:01 darrachequesne

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.

bohdankovt avatar Jan 10 '24 19:01 bohdankovt

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?

darrachequesne avatar Feb 13 '24 16:02 darrachequesne

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

dmitrysl avatar Sep 03 '24 06:09 dmitrysl