Strange WebSocket behavior


#1

Hey, if i need to send several WebSocket messages in a row from server to client - strange thing happens.

I have a SocketService that store all sockets.id when users subscribe to “user” room. For second message (status update) it’s can’t find socket.id at my SocketService class. It’s looks like something had removed it, but SocketService.Delete() never happens (you can see that from log) and client don’t disconnect from server.

I don’t get why that happens. If i send status messages with some delay - all working as it should, but if there are few messages in 1 moment that thing happens. Any ideas what i am doing wrong?

Log

SocketService Add: 3
connected socket user#cjmwr1bya0000vww099sqtnfe 3

Event - WebSocket - updateAccountStatus slipross online
SocketService Get: { userId: 3,  socketList: { '3': 'user#cjmwr1bya0000vww099sqtnfe' } }
SocketService Found: 3

Event - WebSocket - updateAccountStatus slipross playing
SocketService Get: { userId: 3, socketList: {} }

WebSocket UserController

'use strict';

const SocketService = use('App/Services/SocketService');

class UserController {
	constructor({ socket, request, auth }) {
		this.socket = socket;
		this.request = request;
		this.auth = auth;

		SocketService.Add(auth.user.id, socket.id);
		console.log('connected socket', socket.id, auth.user.id);
	}

	onMessage(message) {
		console.log('receive message from socket', this.socket.id, message);
	}

	onClose() {
		console.log('disconnected socket', this.socket.id);
		SocketService.Delete(this.auth.user.id);
	}

	onError(error) {
		console.log('socket error', error);
	}
}

module.exports = UserController;

SocketService

let socketList = {};
class SocketService {
	Add(userId, socketId) {
		socketList[userId] = socketId;
		console.log('SocketService Add:', userId);
	}

	Delete(userId) {
		console.log('SocketService Delete:', userId);
		if (!socketList[userId]) return;
		delete socketList[userId];
		console.log('SocketService Deleted');
	}

	Get(userId) {
		console.log('SocketService Get:', { userId, socketList });
		if (!socketList[userId]) return -1;

		console.log('SocketService Found:', userId);
		return socketList[userId];
	}

	ToArray() {
		return Object.values(socketList);
	}
}

module.exports = new SocketService();

WebSocket event that send status updates to client. Here is all magic happens.

'use strict';

const Ws = use('Ws');
const SocketService = use('App/Services/SocketService');
const WebSocket = (exports = module.exports = {});

WebSocket.updateAccountStatus = async (dbAccount, status, data) => {
	const { account } = dbAccount;
	console.log('Event - WebSocket - updateAccountStatus', account, status);

	const user = await dbAccount.user().fetch();
	if (!user) return;

	const socketId = SocketService.Get(user.id);
	if (socketId === -1) return;

	const subscriptions = Ws.getChannel('user').topic('user');
	if (!subscriptions) return;

	data.account = account;
	data.status = status;

	await subscriptions.emitTo(
		'message',
		{
			type: 'status',
			data
		},
		[socketId]
	);
};