socket.on方法的奇怪问题

时间:2022-11-22 23:02:35

I am facing a strange issue with calling socket.on methods from the Javascript client. Consider below code:

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

Here basically I am calling a cpuUsage event which is emitted by socket server, but for each iteration I am getting the same value. This is the output:

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

0.03549148310035006
0.03549148310035006
0.03549148310035006
0.03549148310035006

Edit: Server side code, basically I am using node-usage library to calculate CPU usage:

编辑:服务器端代码,基本上我使用节点使用库来计算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);
    });
});

Where as in the server side, I am getting different values for each emit and socket.on. I am very much feeling strange why this is happening. I tried setting data = null after each socket.on call, but still it prints the same value. I don't know what phrase to search, so I posted. Can anyone please guide me?

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

Please note: I am basically Java developer and have a less experience in Javascript side.

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

3 个解决方案

#1


1  

You are making the assumption that when you use .emit(), a subsequent .on() will wait for a reply, but that's not how socket.io works.

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

Your code basically does this:

你的代码基本上是这样的:

  • it emits two getLoad messages directly after each other (which is probably why the returning value is the same);
  • 它直接发出两个getLoad消息(这可能是返回值相同的原因);
  • it installs two handlers for a returning cpuUsage message being sent by the server;
  • 它为服务器发送的返回cpuUsage消息安装了两个处理程序;

This also means that each time you run your loop, you're installing more and more handlers for the same message.

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

Now I'm not sure what exactly it is you want. If you want to periodically request the CPU load, use setInterval or setTimeout. If you want to send a message to the server and want to 'wait' for a response, you may want to use acknowledgement functions (not very well documented, but see this blog post).

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

But you should assume that for each type of message, you should only call socket.on('MESSAGETYPE', ) once during the runtime of your code.

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

EDIT: here's an example client-side setup for a periodic poll of the data:

编辑:这是一个定期轮询数据的客户端设置示例:

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

#2


1  

Use this line instead:

请改用此行:

var socket = io.connect('iptoserver', {'force new connection': true});

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

Replace iptoserver with the actual ip to the server of course, in this case localhost.

当然,将iptoserver替换为服务器的实际ip,本例为localhost。

Edit. That is, if you want to create multiple clients.

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

Else you have to place your initiation of the socket variable before the for loop.

否则,您必须在for循环之前放置套接字变量。

#3


1  

I suspected the call returns average CPU usage at the time of startup, which seems to be the case here. Checking the node-usage documentation page (average-cpu-usage-vs-current-cpu-usage) I found:

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

By default CPU Percentage provided is an average from the starting time of the process. It does not correctly reflect the current CPU usage. (this is also a problem with linux ps utility)

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

But If you call usage.lookup() continuously for a given pid, you can turn on keepHistory flag and you'll get the CPU usage since last time you track the usage. This reflects the current CPU usage.

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

Also given the example how to use it.

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

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

});

#1


1  

You are making the assumption that when you use .emit(), a subsequent .on() will wait for a reply, but that's not how socket.io works.

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

Your code basically does this:

你的代码基本上是这样的:

  • it emits two getLoad messages directly after each other (which is probably why the returning value is the same);
  • 它直接发出两个getLoad消息(这可能是返回值相同的原因);
  • it installs two handlers for a returning cpuUsage message being sent by the server;
  • 它为服务器发送的返回cpuUsage消息安装了两个处理程序;

This also means that each time you run your loop, you're installing more and more handlers for the same message.

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

Now I'm not sure what exactly it is you want. If you want to periodically request the CPU load, use setInterval or setTimeout. If you want to send a message to the server and want to 'wait' for a response, you may want to use acknowledgement functions (not very well documented, but see this blog post).

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

But you should assume that for each type of message, you should only call socket.on('MESSAGETYPE', ) once during the runtime of your code.

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

EDIT: here's an example client-side setup for a periodic poll of the data:

编辑:这是一个定期轮询数据的客户端设置示例:

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

#2


1  

Use this line instead:

请改用此行:

var socket = io.connect('iptoserver', {'force new connection': true});

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

Replace iptoserver with the actual ip to the server of course, in this case localhost.

当然,将iptoserver替换为服务器的实际ip,本例为localhost。

Edit. That is, if you want to create multiple clients.

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

Else you have to place your initiation of the socket variable before the for loop.

否则,您必须在for循环之前放置套接字变量。

#3


1  

I suspected the call returns average CPU usage at the time of startup, which seems to be the case here. Checking the node-usage documentation page (average-cpu-usage-vs-current-cpu-usage) I found:

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

By default CPU Percentage provided is an average from the starting time of the process. It does not correctly reflect the current CPU usage. (this is also a problem with linux ps utility)

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

But If you call usage.lookup() continuously for a given pid, you can turn on keepHistory flag and you'll get the CPU usage since last time you track the usage. This reflects the current CPU usage.

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

Also given the example how to use it.

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

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

});