Socket.IO clients to receive offline messages when coming back

Mozart picture Mozart · Oct 30, 2014 · Viewed 8.8k times · Source

Environment:

Nodejs+Socketio

Problem:

  1. client A and client B both connect to server;
  2. client B is offline;
  3. client A sends a message to client B(client B still offline);
  4. client B connect to server again;
  5. [Problem] client B can't receive the message from A;

Server Code

var clients = {};
io.sockets.on('connection', function (socket) {
socket.on('online', function (data) {
    if (!clients[data.username]) {
        clients[data.username] = socket;
    }
    io.sockets.emit('message',  data.user + 'online now');
});
socket.on('say', function (data) {
    if (data.to == 'all') {
        io.sockets.emit('message', data.message);
    } else { //to specific client
        clients[data.to].emit('message', data.message);
    }
});
});

Description

client B connected to server at one place first.During the period of client B's offline, client A sent messages to client B. Then client B connect to server at another place again, and client B needs to receive those message from client A. How to make it work?

Answer

Matt picture Matt · Dec 30, 2014

The amount of code I would have to write would be fairly large to create a solution if I consider which db and it's config, and client. You basically have to persist your messages in a database. As messages come in you would have to write to your conversation object (or whatever is representing the chat messages between clients).

socket.on('say', function (data) {
    // pseudo code to save conversation
    // var conversation = db.getConversation();
    // conversation.addMessage(data.message);
    // conversation.save();
    if (data.to == 'all') {
        io.sockets.emit('message', data.message);
    } else { //to specific client
        clients[data.to].emit('message', data.message);
    }
});

Then you would have to get all messages from the database when a client joins.

socket.on('online', function (data) {
    if (!clients[data.username]) {
        clients[data.username] = socket;
    }
    // pseudo code to get messages and display to user on first load
    // var conversation = db.getConversation();
    // var messages = conversation.getLast10Messages();
    // messages.forEach(function(message) { 
    //     clients[data.username].emit('message', message);
    // });
    io.sockets.emit('message',  data.user + 'online now');
});