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

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

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

我认为您通过使用不同的命名空间造成了不必要的矫枉过正。下面是实现相同功能的更清晰的工作示例:

服务器.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);

客户端.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('');
    });
});

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

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

最新更新