node.js / socket.io - 跟踪客户端

joh*_*yan 6 javascript json websocket node.js socket.io

亲爱的朋友们,我在尝试跟踪聊天中的登录用户时遇到了一个小问题。聊天基于两个独立的频道,在命名空间的帮助下工作:

  1. chatInfra - 处理登录用户并发送欢迎消息。
  2. chatCom - 处理用户之间的消息。

我搜索了很多,但我只找到了理论上的解释,即最好的解决方案是将用户存储到数组中。因此,我试图通过将登录用户存储在数组中然后遍历它们来保持对登录用户的跟踪,但结果仍然不好。

问题是进入聊天后,屏幕上只显示第一个登录用户的名称,而看不到第二个用户的名称。

这是我的服务器端代码,我试图将用户存储到clients数组中:

    var clients = [];

    var chatInfra = io.of("/chat_infra").on("connection", function(socket){
        socket.on("set_name", function (data) {
          clients.push(data.name);
          socket.emit('name_set', data);
          socket.send(JSON.stringify({
             type:'serverMessage',  
             message:'Welcome!' 
         }));
        socket.broadcast.emit('user_entered', data);
        });
    });

    var chatCom = io.of("/chat_com").on("connection", function (socket) {
        socket.on('message', function (message) {
            message = JSON.parse(message);
            for(var key in clients){

               if(message.type == "userMessage"){
                  message.username = clients[key];
                  console.log('message : ', message);
                  socket.broadcast.send(JSON.stringify(message));
                  message.type = "myMessage";
                  socket.send(JSON.stringify(message));
               }
            }

        });
    });
Run Code Online (Sandbox Code Playgroud)

这是它在浏览器中的外观: http //screencast.com/t/lshnfcGZ8E8

这是完整的代码:https : //gist.github.com/johannesMatevosyan/0b9f7e588338dbb6b7f5

cvi*_*ejo 5

我认为您通过使用不同的命名空间来创建不必要的矫枉过正。这是实现相同功能的更清晰的工作示例:

服务器.js

var app    = require("express")();
var server = require("http").Server(app);
var io     = require("socket.io")(server);

var chat = io.of("/chat").on("connection", function(socket){

    socket.on("set_name", function (data) {

        socket.username = data.name;

        socket.emit("name_set", data);
        socket.emit("message", {
            type    :"serverMessage",
            message :"Welcome!" 
        });
        chat.emit("message", {
            type    :"serverMessage",
            message : data.name + " has joined the room.!"
        });
    });

    socket.on("message", function (message) {
        message.username = socket.username;
        chat.emit("message", message);
    });
});


app.get("/", function (req, res) {
    res.sendfile(__dirname + "/index.html");
});

server.listen(3000);
Run Code Online (Sandbox Code Playgroud)

客户端.js

var socket = io.connect('http://localhost:3000/chat');

socket.on('name_set', function (data) {
    $('#nameform').hide();
    $('#messages').append('<div class="systemMessage">Hello ' + data.name + '</div>');
});

socket.on('message', function (message) {
    var userNameHtml = message.username ? '<span class="name">' + message.username + ':</span>' : '';
    $('#messages').append('<div class="' + message.type + '">' + userNameHtml + message.message + '</div>');
});

$(function () {

    $('#setname').click(function () {
        socket.emit("set_name", { name: $('#nickname').val() });
    });

    $('#send').click(function () {
        socket.emit("message", {
            message : $('#message').val(),
            type    : 'userMessage'
        });
        $('#message').val('');
    });
});
Run Code Online (Sandbox Code Playgroud)

我认为您不需要为 单独的事件处理程序user_entered,因为您将其视为常规消息而不对事件执行任何其他操作。还有一些事情:

  • 不需要先连接服务器再连接命名空间地址,连接到后者就好了。
  • 不要在回调中设置事件侦听器,这将导致多次设置它们。