Node.js 多个异步数据发送的正确方法是什么?

Node.js 多个异步数据发送的正确方法是什么?,node.js,websocket,socket.io,Node.js,Websocket,Socket.io,我正在设计一个网页,每页使用大量实时图形。但活跃用户不会超过10-15人。 每个页面都可以有自己的刷新间隔。使用服务器端的Socket.IO使用WebSocket发送数据。 我的第一种方法是页面加载,客户端js将查找图形元素。有关图形的详细信息存储在HTML数据属性中。客户端将向Node.JS服务器发送带有属性的图形。我的问题是如何在服务器端创建异步函数以将数据发送回客户端。 编辑:这只是我尝试做的一个例子。例如,如果第1页有4个不同的图形,第2页有另外5个不同的图形,我不想每次向每个页面发送9

我正在设计一个网页,每页使用大量实时图形。但活跃用户不会超过10-15人。 每个页面都可以有自己的刷新间隔。使用服务器端的Socket.IO使用WebSocket发送数据。 我的第一种方法是页面加载,客户端js将查找图形元素。有关图形的详细信息存储在HTML数据属性中。客户端将向Node.JS服务器发送带有属性的图形。我的问题是如何在服务器端创建异步函数以将数据发送回客户端。 编辑:这只是我尝试做的一个例子。例如,如果第1页有4个不同的图形,第2页有另外5个不同的图形,我不想每次向每个页面发送9个图形的数据。我想单独发送数据。仅以2000毫秒的间隔向第1页发送4个图形数据,以10000毫秒的间隔向第2页发送5个图形数据

这是我目前的做法。为了简单起见,我假设每页只有一个图表

server.on("connection", function(socket) {
    var charts = socket.handshake.query.charts;
    console.log("client connected with: " + charts);
    users.push(socket);
    socket.on('disconnect', function(){
        users.splice(users.indexOf(socket), 1);
    });
});
它只存储活动客户端

var myVar = setInterval(myTimer, 1000);

function myTimer() {
  for(var i = 0; i<users.length; i++){
      users[i].emit('test', 'data');    
      console.log("data sent to: " + users[i].id);
  }
}


var charts = [];
var elements = document.getElementsByClassName("live-chart");
var i;
for (i = 0; i < elements.length; i++) {
    var content = elements[i].getAttribute('data-content');
    var type = elements[i].getAttribute('data-type');
    var interval = elements[i].getAttribute('data-interval');
    var chart = {content: content, type:type, interval: interval};
    charts.push(chart);
}
var socket = io.connect("http://step.demo:3000", { query: "charts=" + JSON.stringify(charts) });

我一直在思考如何根据每个客户端的刷新设置创建大量异步函数,然后在断开连接事件时停止它们。或者还有其他方法可以做到这一点,比如在中添加CRON作业,但间隔要短得多。

如果您试图向不同的客户端发送不同的数据,那么服务器需要知道哪些数据要发送到哪些客户端,服务器需要在下一个间隔存储这些数据,它可以查找哪些数据发送到clientA并仅发送其数据,哪些数据发送到clientB并仅发送该数据

我不知道您的页面是如何初始化的,也不知道如何初始化图形以了解所有选项。如果没有这些信息,最简单的方法是客户端只向服务器发送一条消息,告诉服务器它需要哪些图形上的数据,然后服务器就可以将这些数据存储在客户端套接字对象上

然后,当您向该客户机发送数据时,可以查看其套接字对象上的自定义属性,该属性列出了它想要的图形,并且只发送这些图形

因为,在连接时,您似乎将图形作为查询参数发送,所以您可以在连接时捕获该信息

server.on("connection", function(socket) {
    try {
         socket._charts = JSON.parse(socket.handshake.query.charts);
         console.log("client connected with: " + socket._charts);
         users.push(socket);
    } catch(err) {
         console.log(err);
    }
    socket.on('disconnect', function(){
        users.splice(users.indexOf(socket), 1);
    });
});
然后,每当您遍历套接字时,要向它们发送更新的数据,您可以访问
socket.\u charts
,查看它需要哪些图表的数据


如果您试图为每个新连接启动一个新的间隔计时器(我不知道您为什么会这样做),您可以这样做:

server.on("connection", function(socket) {
    let interval;
    try {
         let charts = JSON.parse(socket.handshake.query.charts);
         console.log("client connected with: " + charts);
         users.push(socket);
         interval = setInterval(() => {
             // interval timer for each separate socket
             // process your interval here using the charts variable
             socket.emit(...);    // send data to just the one socket in this interval
         }, 1000);
    } catch(err) {
         console.log(err);
    }
    socket.on('disconnect', function(){
        users.splice(users.indexOf(socket), 1);
        clearInterval(interval);                 // stop timer for this socket
    });
});

要理解你在寻求什么帮助或者你想解决什么问题有点困难。当前代码每秒向每个当前连接的客户端发送更新。你有什么问题?仅供参考,您不必手动跟踪每个连接并手动迭代它们
io.emit()
将为您发送到所有当前连接的客户端。服务器端socket.io库中已存在该功能,其中
io.emit()
是socket.io的服务器端实例。
io.emit()
将向所有客户端发送所有数据。我只想发送该页面所需的数据。例如,如果当前页面有4个不同的图形,而其他页面有另外5个不同的图形,我不想每次发送9个图形的数据。我想单独发送数据。那么,你要么需要让页面请求它想要的数据,然后你可以用这些数据进行响应,要么你必须让客户端告诉你它想要哪些图形,然后你存储这些图形,并在下一个时间间隔只向它发送这些数据。在您的问题中,我看不出这是您想要的,因为您当前的代码片段只向所有客户端发送相同的数据,这就是我建议
io.emit()
的原因。我还是不知道你想让我们帮什么忙。请编辑您的问题以澄清您需要的帮助。仅供参考,node.js中的所有网络都是异步的,因此您不需要“创建大量异步函数”。你只需要做网络,它自然是异步的。对不起,我太兴奋了,忘记了一些代码块。我把它们添加到了主帖子中。谢谢,实际上这就是我要做的。让我们假设我的套接字对象有一个自定义属性,其中包含图形细节和间隔。当我使用setInterval创建函数时,即使套接字断开连接,服务器也会尝试向它发送数据。我应该使用套接字关系存储这些setInterval函数,并在断开连接时停止它们。@kenarsuleyman-服务器不会尝试将数据发送到已断开连接的套接字,因为您将从阵列中删除它。为什么您认为每个插座都需要一个单独的间隔?在一个主循环中,以固定的间隔迭代所有客户端并向它们发送数据是一个解决方案,而且易于实现。但是我尝试做的每一个套接字都有它自己的间隔。为此,我根据套接字对象创建了一个setInterval函数。使用这种方法,即使套接字断开连接,setInterval函数仍会运行。@kenarsuleyman-抱歉,但这对我来说毫无意义。为什么要在套接字断开连接时继续间隔。这听起来像是在浪费服务器资源,因为这个时间间隔与此无关(客户端已断开连接)。事实上,如果您这样做,那么当客户端在将来某个时间返回您的站点时,您将为它启动另一个间隔,随着时间的推移,您的间隔数将不断增加,从而浪费越来越多的服务器CPU。这就是为什么我正在寻找一种方法来停止/清除客户端在断开连接时的所有间隔。
server.on("connection", function(socket) {
    let interval;
    try {
         let charts = JSON.parse(socket.handshake.query.charts);
         console.log("client connected with: " + charts);
         users.push(socket);
         interval = setInterval(() => {
             // interval timer for each separate socket
             // process your interval here using the charts variable
             socket.emit(...);    // send data to just the one socket in this interval
         }, 1000);
    } catch(err) {
         console.log(err);
    }
    socket.on('disconnect', function(){
        users.splice(users.indexOf(socket), 1);
        clearInterval(interval);                 // stop timer for this socket
    });
});