2016-02-18 255 views
3

親愛的朋友們,我在嘗試跟蹤聊天記錄的用戶時遇到了一個小問題。聊天是基於兩個獨立通道和命名空間的工作有所幫助: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

回答

3

我認爲你正在通過使用不同的命名空間來創建一個不必要的矯枉過正。這裏有一個更清晰的工作示例實現相同的功能:

server.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); 

client.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,因爲您將它視爲常規消息,而不是對事件做任何其他事情。還有一些東西:

  • 你不需要先連接到服務器,然後連接到命名空間地址,連接到後面就好了。
  • 不要在回調中設置事件偵聽器,這將導致多次設置它們。
+0

感謝您的回答,但它顯示未定義'message.username = client.username;'值。 – johannesMatevosyan

+0

這是執行順序的問題,我想。您的客戶端代碼中存在其他錯誤。例如,您在'name_set'事件處理程序中設置新的事件偵聽器,每當您收到消息時。 – cviejo

+0

將嘗試使用工作版本進行更新。 – cviejo

相關問題