Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Socket.io:如何限制从客户端向websocket服务器发送的数据的大小_Javascript_Node.js_Socket.io - Fatal编程技术网

Javascript Socket.io:如何限制从客户端向websocket服务器发送的数据的大小

Javascript Socket.io:如何限制从客户端向websocket服务器发送的数据的大小,javascript,node.js,socket.io,Javascript,Node.js,Socket.io,我有一个带有socket.io的node.js服务器。我的客户端使用socket.io连接到node.js服务器 数据通过以下方式从客户端传输到服务器: 论客户 var Data = {'data1':'somedata1', 'data2':'somedata2'}; socket.emit('SendToServer', Data); 在服务器上 socket.on('SendToServer', function(Data) { for (var key in Data) {

我有一个带有socket.io的node.js服务器。我的客户端使用socket.io连接到node.js服务器

数据通过以下方式从客户端传输到服务器:

论客户

var Data = {'data1':'somedata1', 'data2':'somedata2'};
socket.emit('SendToServer', Data);
在服务器上

socket.on('SendToServer', function(Data) {
    for (var key in Data) {
           // Do some work with Data[key]
    }
});
假设有人修改了他的客户机并向服务器发送了一大块数据。例如:

var Data = {'data1':'somedata1', 'data2':'somedata2', ...and so on until he reach for example 'data100000':'data100000'};
socket.emit('SendToServer', Data);
由于服务器上的此循环

for (var key in Data) {
       // Do some work with Data[key]
}
。。。服务器将花费很长时间来循环处理所有这些数据

那么,预防此类情况的最佳解决方案是什么

谢谢

编辑:

我使用此函数验证对象:

function ValidateObject(obj) {
    var i = 0;
    for(var key in obj) {
        i++;
        if (i > 10) { // object is too big
            return false;
        }
    }
    return false;
}

也许
销毁缓冲区大小
是您所需要的

从:

  • 销毁缓冲区大小默认为
    10E7
由HTTP传输使用。Socket.IO服务器将HTTP请求主体缓冲到该限制。此限制不适用于websocket或FlashSocket


好吧,我将使用Javascript的一面。。。假设您不想让用户超过某个数据限制,您可以:

var allowedSize = 10;

Object.keys(Data).map(function( key, idx ) {
    if( idx > allowedSize ) return;
    // Do some work with Data[key]
});

这不仅允许您正确地循环对象的元素,还允许您轻松地进行限制。(显然,这也会破坏您自己的预设请求)

因此,最简单的方法就是在对数据进行任何操作之前检查数据的大小

socket.on('someevent', function (data) {
    if (JSON.stringify(data).length > 10000) //roughly 10 bytes
        return;

    console.log('valid data: ' + data);
});
老实说,这有点低效。客户端发送消息,socket.io将消息解析为对象,然后获取事件并将其转换回字符串

如果您想更高效,那么在客户端,您应该强制执行消息的最大长度

为了获得更高的效率(并防止恶意用户),当数据包进入Socket.io时,如果数据包的长度过长,则应丢弃它们。您要么需要找到一种方法来扩展原型以实现您想要的功能,要么需要提取源代码并自己修改它。此外,我还没有研究socket.io协议,但我确信您需要做的不仅仅是“丢弃”数据包。另外,有些数据包是ack-back和nack-back,所以您也不想弄乱它们


旁注:如果您只关心键的数量,则可以使用返回键数组的
Object.keys(obj)

if (Object.keys(obj).length > 10)
    return;

<>你可能会考虑切换到直接处理输入流。

通过这种方式,您应该连接块并最终手动解析json输入,但当输入数据长度超过您决定的阈值时,您有机会关闭连接

否则(使用socket.io方法)在收到整个数据流之前不会调用回调。这不会停止js主线程的执行,而是浪费内存、cpu和带宽

另一方面,如果您的唯一目标是避免处理算法过载,那么您可以通过计算接收对象中的元素来继续限制它。例如:

if (Object.keys(data).length > n) return; // Where n is your maximum acceptable number of elements.
// But, anyway, this doesn't control the actual size of each element.

编辑:因为问题是关于“如何处理服务器过载”,所以您应该使用gninx检查负载平衡-如果一个客户端造成瓶颈,您可以使用其他服务器。其他服务器将可用。即使您解决了这个问题,仍然存在其他问题,比如客户端发送几个小数据包等等

Socket.io-library似乎有点问题,在websockets层无法管理太大的消息,三年前有一个pull-request,它给出了解决问题的方法:

然而,由于WebSockets-protocol的数据包大小是有限的,所以若达到一定的大小,它将允许您停止对数据包的处理。最有效的方法是在将数据包传输到JavaScript堆之前。这意味着您应该手动处理WebSocket转换-这是socket.io为您所做的,但它不考虑数据包大小

如果您想实现自己的websocket层,使用此websocket节点实现可能会很有用:


如果您不需要支持较旧的浏览器,那么使用这种纯WebSocket方法可能是合适的解决方案。

您说过该限制不适用于WebSocket。但这正是我需要的。我需要对通过WebSocket发送的数据进行限制。这对于服务器端验证很好。但是我想防止大块数据被自动拒绝,这样它们甚至在服务器端代码中都不可用。如果有人发送一个消耗所有服务器内存的大对象,该怎么办?在编写使用WebSocket的应用程序时,这是我应该考虑的问题,还是我应该只在代码中进行服务器端验证,仅此而已?@user3179196您可能希望在此处检查接受的答案;)您可以重写emit()和broadcast()函数,以阻止发送大数据。有人仍然可以破解您的客户端代码,因此您也希望使用服务器端验证。如果大小以字节而不是键为单位,您就不能将其字符串化并检查长度吗?不幸的是,您丢失了socket.io提供的会话重新连接和客户端自动重新连接等功能。