【问题标题】:Socket reference in Socket.IOSocket.IO 中的套接字引用
【发布时间】:2012-03-12 05:27:50
【问题描述】:

我是 nodejs 的新手,正在尝试使用 socket.io。我正在尝试将消息发送到特定的套接字,所以我想我会存储对套接字的引用。

var controls = {};
var clients = {};

var control = io
  .of("/control")
  .on("connection", function(socket){
    socket.on("connect_player", function(data){
      var id = data.screen_id;
      controls[socket.id] = id;
    });

    socket.on("msg", function(data){
      id = controls[socket.id]
      player.socket(clients[id]).emit("msg", data);
    });
  });

var player = io
  .of("/player")
  .on("connection", function(socket){
    socket.on("set_id", function(id){
      clients[id] = socket.id
    });
  });

我首先启动一个网页,该网页连接到“播放器”命名空间并显示一个 id(硬编码)。然后另一个网页连接到与播放器具有相同 ID 的“控制”命名空间,现在控制器应该能够向该特定播放器发送消息,但这可以工作一段时间然后失败。

在它工作期间,我可以将消息从控制页面发送到特定的播放器页面。

我在播放器命名空间停止工作后查看了套接字 ID,发现套接字 ID 与最初的不同。

我想我在这里做错了什么或者对概念有错误的理解。我该如何解决这个问题。

编辑:

我为“重新连接”事件添加了侦听器,发现 socket.id 的值在每个“重新连接”事件之后都会发生变化。所以控件和客户端的 socket.id 值无效,这导致了我的问题。有没有办法克服这个问题。

【问题讨论】:

    标签: node.js socket.io


    【解决方案1】:

    最新的 socket.io 支持房间。那么这个怎么样?对于每个连接,为此连接设置一个唯一的 ID(例如唯一的用户名 - 这与会话一起使用非常好 - 或任何你想要的)。然后就可以使用了

    io.on('connection', function(socket) {
       // retrieve the ID from socket
       socket.join('/priv/'+ID);
    });
    

    那么你可以在msghandler中做如下操作:

    // get the ID
    io.sockets.in('/priv/'+ID).emit("msg", data);
    

    此时您可以确定消息已发送给您想要的用户。当然,您需要确保客户端重新连接时 ID 不会更改。就像我之前提到的 - 这可以通过将会话 cookie 发送到服务器并从会话中检索 ID 来完成。

    我认为这是唯一可接受的解决方案,因为客户端可能会重新连接很多次,并且您希望其他客户端通过例如(唯一)名称来识别此特定客户端。

    【讨论】:

    • 我已经编辑了我的问题。我面临的问题是由于我使用 socket.id 作为参考,重新连接后似乎发生了变化。
    • 没错。这就是为什么我建议不要使用它的原因。为每个客户定义和设置您自己的 ID 并使用房间来维护私人消息。
    • 根据我的经验,您应该使用 RedisStore 来使用“Room”功能。因为 Socket.io 使用了 Redis 的 subscribe、unsubscribe 特性来实现“Room”
    • 我厌倦了@freakish,它也不工作了..它的行为就像我的原始代码一样......我像anand建议的那样更改设置,它似乎正在工作..但我不知道这样做是否正确。
    • @josnidhin 你是什么意思它不工作?它必须工作!你一定做错了什么。 :) 当客户端连接时,他必须将他的名字发送到服务器。服务器存储名称并在此特定连接上运行sock.join('/priv/'+name);。它必须工作,它不可能不工作。 :)
    【解决方案2】:

    您可以尝试将心跳间隔设置为

     io.set('heartbeat interval', 20); 
     io.set('heartbeat timeout', 60); 
    

    【讨论】:

    • 我认为这对我没有帮助。我试过了,没有任何改变。感谢您的建议。
    • 你使用的是哪个版本的socket.io?
    • 假设它是 v 0.9.1。此版本更改了服务器端的心跳超时和间隔默认值(60 秒和 25 秒),并实施了客户端心跳检查。对不起。我错过了之前评论中的另一个设置。它应该是 io.set('heartbeat interval', 20); io.set('心跳超时', 60);默认情况下,客户端超时与服务器端轮询间隔相同(此处为 25 秒)。消息通过互联网(甚至是本地主机)需要时间,典型的延迟约为 5 秒。所以这个设置应该可以解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多