Socket.io - не может отправлять сообщения в комнаты - PullRequest
0 голосов
/ 08 октября 2018
socket.on('join room', function (data) {
    var room = data.room;
    var msg = "<span style='color:darkgreen;'>" + data.user + " has joined chat.</span>";

    socket.join(room, function () {
        console.log(socket.id + " now in rooms ", socket.rooms);
    });

    io.in(room).emit('system message', msg);
});

Если я изменю io.in(room) на socket.broadcast, системное сообщение проходит.По какой-то причине, он не будет отправлять сообщения в определенные комнаты, он просто ничего не делает, также нет ошибок.Есть идеи, что здесь не так?

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

socket.join() является асинхронным.Он еще не завершен, когда вы пытаетесь отправить в комнату, поэтому сообщение не отправляется в этот сокет, потому что его еще нет в комнате.Итак, измените это:

socket.join(room, function () {
    console.log(socket.id + " now in rooms ", socket.rooms);
});

io.in(room).emit('system message', msg);

на следующее:

socket.join(room, function () {
    console.log(socket.id + " now in rooms ", socket.rooms);
    io.in(room).emit('system message', msg);
});

Итак, в этой новой версии вы не отправляете в комнату, пока ПОСЛЕ завершения .join(), а неbefore.

Подобный пример вы можете увидеть прямо в документе socket.io здесь .

0 голосов
/ 08 октября 2018

Кажется, приведенный выше код находится на сервере, правильно?

Попробуйте выполнить следующее, при необходимости адаптируйте его под свои нужды:

io.on('connection', function (socket) {
    // You should expect ONLY one user connected, 
    // > otherwise, you're creating multiple sessions :)
    console.log('a user connected');
    socket.on('join room', function (data) {
        var room = data.room;
        console.log('Room: ', room);
        var msg = "<span style='color:darkgreen;'>" + data.user + " has joined chat.</span>";

        socket.join(room); // No callback needed
        console.log(socket.id + " now in rooms ", socket.rooms);
        io.to(room).emit('system message', msg);
        // Change it to io.to(room)

    });
});

Я заметил, что вы проситеприсоединиться к клиенту с помощью:

$(".channelChange").click( function(evt) {
    var socket = io();
    $("#messages").html("");
    evt.stopPropagation();
    if($.inArray(evt.currentTarget, $(this).children())){
        console.log("user moved to " + evt.currentTarget.id);
    }
    setCookie("currentRoom", evt.currentTarget.id, 1);
    $(".roomName").html("<span class='3Dtext'>" + evt.currentTarget.id + "</span>");
    $("#enter-sound").get(0).play();
    getMessages(getCookie("currentRoom"));
    // Here you ask to join room
    socket.emit('join room', { user: getCookie("username"), room: getCookie("currentRoom") });
})

и получить системное сообщение on:

   $(function(){
        var socket = io();
        socket.on('system message', function(msg) {
            alert("test");
            $('#messages').append($('<div class="systemMessage">').html(msg));
            var height = $("#messages")[0].scrollHeight;
            $.mobile.silentScroll(height);
    });

Основная проблема, как вы увидите, заключается в том, что выВы звоните io() каждый раз, это создало различные сеансы, 1. Первый сеанс присоединяется к комнате 2. Другой сеанс будет ожидать системное сообщение

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

const setIo = (function (){
        const _io = io();
        return () => _io;
    })()

А затем Замените все объявления io () на: var socket = setIo();

, такиеas:

$(".channelChange").click( function(evt) {
    var socket = setIo();
    $("#messages").html("");
    evt.stopPropagation();

Это создаст один сеанс io () вместо разных, и будет использовать его каждый раз при вызове setIo()

В конечном итоге вы увидите всплывающее предупреждениеup:

enter image description here

...