turntwo
turntwo

Reputation: 2520

Maintain socketio conection to each new tab opened by the same user

I'm making an application for our website where users can send chat messages with each other. I've managed to do this successfully using nodejs and socketio. I have a header with some sort of notification icon just like facebook that can be seen in all the pages. Now if the user opens multiple tabs and he receives a message, then all open tabs should see the icon light up. I've gotten this to work by tracking the socket connections opened by users through a 2D array of sockets:

var container = {};
io.sockets.on( 'connection', function(client) {

    client.on('set account online', function(username) {
        if (!(username in container)) {
            console.log(username + " is now Online" );
            container[username] = [];
        }
        client.username = username;
        container[username].push(client);
    });

    client.on('set account offline', function(username) {
        if (username in container) {
            delete container[username];
            console.log(username + " is now Offline" );
        }
    });

And then when a message is sent I iterate through the appropriate array element

   client.on('send message', function(data) {
        if (data.recipient in container) {
            var clients = container[data.recipient];
            for(var i = 0; i < clients.length;i++){
                clients[i].emit('send message', {recipient: data.recipient, message: data.message });
            }
        }
    });

That's working well and all (not sure how well coded it is though). The problem is if the user closes a tab, the socket for that tab still exists in the container variable and node would still try to emit to that socket if a message is received for that particular user. Also it just feels cleaner to un-track any disconnected socket.

I've been thinking about this and I think I have to tie the socket disconnect event to the client side's onbeforeunload event and we all know how that performs across different browsers. Any suggestion regarding what's the proper way to splice off disconnected sockets from the container array?

Upvotes: 0

Views: 2934

Answers (1)

Ben Fortune
Ben Fortune

Reputation: 32127

As per my comment:

You should really be implementing rooms. On each connection each user should join their own room, any additional connections from the same user should join this room. You can then emit data to the room and each client inside it will receive the data.

Your code can be changed to:

io.sockets.on('connection', function(client) {

    client.on('set account online', function(username) {
        client.join(username);
    });

    client.on('set account offline', function(username) {
        client.leave(username);
    });

    client.on('send message', function(data) {
        io.to(data.recipient).emit('send message', {
            recipient: data.recipient,
            message: data.message
        });
    });
});

Upvotes: 3

Related Questions