socket.on方法的奇怪问题

时间:2014-01-06 10:14:57

标签: javascript node.js sockets socket.io

我遇到了一个从Javascript客户端调用socket.on方法的奇怪问题。请考虑以下代码:

for(var i=0;i<2;i++) {
  var socket = io.connect('http://localhost:5000/');
  socket.emit('getLoad');
  socket.on('cpuUsage',function(data) {
        document.write(data);
  });
 }

这里基本上我正在调用由socket服务器发出的cpuUsage事件,但是对于每次迭代,我得到相同的值。这是输出:

0.03549148310035006
0.03549148310035006
0.03549148310035006
0.03549148310035006

编辑:服务器端代码,基本上我使用节点使用库来计算CPU使用率:

socket.on('getLoad', function (data) {

    usage.lookup(pid, function(err, result) {
        cpuUsage = result.cpu;
        memUsage = result.memory;
        console.log("Cpu Usage1: " + cpuUsage);
        console.log("Cpu Usage2: " + memUsage);
        /*socket.emit('cpuUsage',result.cpu);
        socket.emit('memUsage',result.memory);*/
        socket.emit('cpuUsage',cpuUsage);
        socket.emit('memUsage',memUsage);
    });
});

在服务器端,我为每个emitsocket.on获取不同的值。我很奇怪为什么会这样。我尝试在每次data = null调用后设置socket.on,但仍会打印相同的值。我不知道要搜索什么短语,所以我发布了。有人可以指导我吗?

请注意:我基本上是Java开发人员,在Javascript方面的经验较少。

3 个答案:

答案 0 :(得分:1)

请改用此行:

var socket = io.connect('iptoserver',{'强制新连接':true});

将iptoserver替换为服务器的实际IP,当然是localhost。

编辑。 也就是说,如果你想创建多个客户端。

否则你必须在for循环之前放置socket变量。

答案 1 :(得分:1)

我怀疑这个调​​用会在启动时返回平均CPU使用率,这似乎就是这种情况。检查节点使用文档页面(average-cpu-usage-vs-current-cpu-usage)我发现:

  

默认情况下,CPU Percentage是起始时的平均值   这个过程的时间。它无法正确反映当前的CPU   用法。 (这也是linux ps实用程序的一个问题)

     

但是如果你为给定的pid连续调用usage.lookup(),你可以   打开keepHistory标志,你将获得自上次以来的CPU使用率   你跟踪使用情况。这反映了当前的CPU使用情况。

还给出了如何使用它的示例。

var pid = process.pid;
var options = { keepHistory: true }
usage.lookup(pid, options, function(err, result) {

});

答案 2 :(得分:1)

您假设当您使用.emit()时,后续的.on()会等待回复,但这不是socket.io的工作方式。

您的代码基本上是这样做的:

  • 它会直接发出两条getLoad条消息(这可能就是返回值相同的原因);
  • 它为服务器发送的返回cpuUsage消息安装了两个处理程序;

这也意味着每次运行循环时,都会为同一条消息安装越来越多的处理程序。

现在我不确定你想要的是什么。如果要定期请求CPU负载,请使用setIntervalsetTimeout。如果要向服务器发送消息并希望“等待”响应,则可能需要使用确认功能(记录不完整,但请参阅this blog post)。

但是你应该假设对于每种类型的消息,你应该只在代码运行期间调用socket.on('MESSAGETYPE', )一次。

编辑:以下是定期轮询数据的客户端设置示例:

var socket = io.connect(...);

socket.on('connect', function() {
  // Handle the server response:
  socket.on('cpuUsage', function(data) {
    document.write(data);
  });

  // Start an interval to query the server for the load every 30 seconds:
  setInterval(function() {
    socket.emit('getLoad');
  }, 30 * 1000); // milliseconds
});