Javascript 如果节点JS中的Socket.IO落后,则丢弃数据包

Javascript 如果节点JS中的Socket.IO落后,则丢弃数据包,javascript,performance,node.js,websocket,socket.io,Javascript,Performance,Node.js,Websocket,Socket.io,我有一个实时传感应用程序,多个客户端,一个处理服务器 我遇到了一个问题,即使用Socket.IO和NodeJS尽可能快地将数据推送到客户端。问题似乎是,从服务器上的emit发送的客户端传入数据开始堆积,而客户端落后(不同步) 有了足够的吞吐量,客户机就能保持良好的性能。是否有任何方法可以强制执行一个策略,服务器/客户端将丢弃任何早于指定时间段的发射 数据被丢弃,客户端应该保持最新,因此我不担心丢失超过2秒的数据。发送易失性消息,如果无法发送,则可以删除这些消息。Socket.IO通常会跟踪客户端

我有一个实时传感应用程序,多个客户端,一个处理服务器

我遇到了一个问题,即使用Socket.IO和NodeJS尽可能快地将数据推送到客户端。问题似乎是,从服务器上的emit发送的客户端传入数据开始堆积,而客户端落后(不同步)

有了足够的吞吐量,客户机就能保持良好的性能。是否有任何方法可以强制执行一个策略,服务器/客户端将丢弃任何早于指定时间段的发射


数据被丢弃,客户端应该保持最新,因此我不担心丢失超过2秒的数据。

发送易失性消息,如果无法发送,则可以删除这些消息。Socket.IO通常会跟踪客户端是否收到消息,但对于易失性消息,此检查不会完成,Socket.IO进程可以继续,而不是等待:

socket.volatile.emit('event', data);
这是文件中所述的内容:

这在功能上基本上是fire和forget,这些消息不是 在客户端无法接收消息时进行内部缓冲 例如,如果客户端存在网络问题或客户端使用 轮询传输,处于请求/响应周期的中间。

因此,如果你的客户错过了几条信息或 您可能希望将其作为易失性消息发送的事件


为了帮助可能遇到此问题的其他人,我设计了一个锁定系统,以便服务器仅在套接字空闲时发布数据

这意味着服务器仍然以尽可能快的速度发布,它只是不会堆叠几个传出的数据请求。请注意,只有当您的邮件被丢弃并且您需要最新信息时,此选项才有效。这还意味着消息之间有一点开销,因为客户机必须通知服务器它已经准备好进行更多操作

然而,这意味着我的应用程序仍然是最新的,不会因为请求堆积而落后,如果您在本地运行一个浏览器,在网络上运行另一个浏览器,这一点在以前是显而易见的

Server.js

var socket = ...; // Create socket

// Create my data, in my project this updates very quickly
// roughly 60 times per second
var my_data = ...;

// Initially set receiving to false as the socket
// has no outgoing data
socket.set('receiving', false);

// Listen for received event, this indicates
// that the client has received an update
// and is now ready to receive more
socket.on('received', function() {
    socket.set('receiving', false);
});

// Function will be called repeatedly to send out data
function update() {
    // Check if the socket is receiving any data
    socket.get('receiving', function(receiving) {
        if(!receiving) {
            // Lock the socket from receiving future updates
            // by setting the receiving variable to true
            socket.set('receiving', true, function() {
                // Now emit data
                socket.emit('update', my_data);
            });
        }
    });

    setTimeout(update, 0); // Recursively call update
}
setTimeout(update, 0); // Start update
var socket = io.connect();

socket.on('update', function(data) {
    // Store the data for processing

    // Tell the server we have received the data
    socket.emit('received');
});
Client.js

var socket = ...; // Create socket

// Create my data, in my project this updates very quickly
// roughly 60 times per second
var my_data = ...;

// Initially set receiving to false as the socket
// has no outgoing data
socket.set('receiving', false);

// Listen for received event, this indicates
// that the client has received an update
// and is now ready to receive more
socket.on('received', function() {
    socket.set('receiving', false);
});

// Function will be called repeatedly to send out data
function update() {
    // Check if the socket is receiving any data
    socket.get('receiving', function(receiving) {
        if(!receiving) {
            // Lock the socket from receiving future updates
            // by setting the receiving variable to true
            socket.set('receiving', true, function() {
                // Now emit data
                socket.emit('update', my_data);
            });
        }
    });

    setTimeout(update, 0); // Recursively call update
}
setTimeout(update, 0); // Start update
var socket = io.connect();

socket.on('update', function(data) {
    // Store the data for processing

    // Tell the server we have received the data
    socket.emit('received');
});

我认为这是不对的。我用volatile进行了测试,但它似乎没有产生任何影响。数据仍在排队等待浏览器接收。它只会尝试在失败的消息尝试中不重新发送数据,情况并非如此。我需要消息生命周期之类的东西,但在文档中找不到任何东西,所以我假设它不存在。可以删除消息的地方只有客户端和服务器。即使要发送带有时间戳的消息,客户端也必须接收它才能删除它。因此,是的,它没有实现。我想我将不得不走客户端定期发送消息号码的路线(递增的号码,与我目前发送的每条消息一起传递),如果这个号码落后太多,我可以跳过服务器的一些发射。虽然不理想,但我认为这可能是仍然使用socket.io的唯一方法。