【问题标题】:Does JavaScript WebSocket.send method block?JavaScript WebSocket.send 方法是否阻塞?
【发布时间】:2013-08-17 06:56:59
【问题描述】:

如果我通过 JavaScript WebSocket 通过其 send 方法发送大的 BlobArrayBuffer... send 方法调用会阻塞直到数据被发送,还是它会异步发送数据的副本以便调用可以立即返回?

一个相关的(未回答的)问题是,从我的解释来看,一系列快速发送是否会导致 onmessage 事件被延迟,正如有人似乎在 Mobile Safari 中描述的那样:Apparent blocking behaviour in JavaScript websocket on mobile Safari

【问题讨论】:

    标签: javascript asynchronous websocket blocking


    【解决方案1】:

    根据bufferedAmount属性的描述,我推断send必须立即返回,否则bufferedAmount > 将始终为零。如果它不为零,则必须从先前的 send 调用缓冲数据,如果 send 缓冲数据,则没有理由阻塞。

    来自http://dev.w3.org/html5/websockets/

    bufferedAmount 属性必须返回的字节数 已排队的应用程序数据(UTF-8 文本和二进制数据) 使用 send() 但是,截至最后一次事件循环开始 执行任务,尚未传输到网络。 (这 因此包括在当前任务执行期间发送的任何文本, 无论用户代理是否能够传输文本 与脚本执行异步。)这不包括框架 协议产生的开销,或由操作完成的缓冲 系统或网络硬件。如果连接关闭,这 属性的值只会随着每次调用 send() 而增加 方法(一旦连接关闭,数字不会重置为零)。

    在这个简单的示例中,bufferedAmount 属性用于确保 更新以每 50 毫秒更新一次的速率发送,如果 网络可以处理该速率,或者网络可以处理的任何速率 处理,如果那太快了。

    var socket = new WebSocket('ws://game.example.com:12010/updates');
    socket.onopen = function () {
        setInterval(function() {
           if (socket.bufferedAmount == 0)
               socket.send(getUpdateData());
        }, 50);
    };
    

    bufferedAmount 属性也可用于使网络饱和 无需以高于网络处理能力的速率发送数据, 虽然这需要随着时间的推移更仔细地监控属性的值。

    【讨论】:

    • 我要看看这个答案有多少票,如果有的话。从逻辑上讲,发送通常没有理由阻止,但我不知道它会如何处理非常大的 Blob 或 ArrayBuffers,例如它是否超过了允许的最大缓冲量。规范说,如果调用 send 并且缓冲区已满,用户代理必须关闭 websocket。
    • 在某些实现中似乎有 2GB 的限制:“所以我们可能想在我们的文档中提到,我们目前支持最多 2 GB 的 Web Socket 消息,包括传入/传出。这是理论上的限制 - -malloc 肯定会在这种大小的移动设备上失败,在这种情况下(根据规范要求)websocket 会失败。” - bugzilla.mozilla.org/show_bug.cgi?id=711003
    猜你喜欢
    • 1970-01-01
    • 2015-04-25
    • 2020-09-16
    • 2011-04-09
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多