Клиенты Socket.IO получат офлайн-сообщения при возврате

Окружающая среда:

Nodejs + Socketio

Проблема:

  • клиент A и клиент B оба подключаются к серверу;
  • клиент B не работает;
  • клиент A отправляет сообщение клиенту B (клиент B все еще не работает);
  • клиент B снова подключится к серверу;
  • [ Проблема] клиент B не может получить сообщение от A;

Код сервера

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

Описание

клиент B, подключенный к серверу в одном месте. В течение периода времени клиента B в автономном режиме клиент отправляет сообщения клиенту B. Затем клиент B снова подключается к серверу в другом месте, а клиенту B необходимо получить это сообщение от клиента A. Как заставить его работать?

Ответ 1

Объем кода, который мне пришлось бы написать, был бы довольно большим, чтобы создать решение, если я рассмотрю, какой db и его config и клиент. В основном вы должны сохранять свои сообщения в базе данных. По мере поступления сообщений вам придется писать на ваш объект беседы (или что-то вроде сообщений чата между клиентами).

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

Затем вам нужно будет получить все сообщения из базы данных при подключении клиента.

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

Ответ 2

используйте очередь сообщений, такую ​​как RabbitMQ. всякий раз, когда сообщение поступает из очереди сокетов в очередь получателя и когда приемник присоединяется, он выберет его из очереди.

Ответ 3

Вы можете указать уникальный идентификатор в качестве имени пользователя для каждого пользователя, сохранить его на стороне сервера или использовать имя пользователя, у вас также есть идентификатор клиента (идентификатор сокета), а затем сохранить их в объекте, теперь для каждого пользователя у вас есть объект, который содержит (имя пользователя или уникальный идентификатор) и идентификатор сокета, теперь легко сохранять сообщения, когда пользователь не в сети, а затем отправлять их пользователю. Перед отправкой каждого события вы можете выполнить поиск идентификатора сокета в подключенном объекте сокетов для socket.if идентификатор сокета существует, вы можете произвести генерацию, в противном случае у вас все еще есть имя пользователя и вы можете сохранять сообщения в базе данных по имени пользователя.

Помните, что вы должны отправлять информацию об объекте получателя (имя пользователя или уникальный идентификатор, а также идентификатор сокета) при каждом излучении от клиента