WebSocket.onmessage 什么时候触发?

When is WebSocket.onmessage triggered?

(1) 打开一个 WebSocket 连接。

var ws = new WebSocket(url);

(2) 建立连接后,发送一条消息,该消息将触发发回响应的 blob。

ws.onopen = function () {
    ws.send('1000000');
}

(3) onmessage是在响应开始时触发还是响应完成时触发?

ws.onmessage = function () {
    // Has the entire blob arrived or has the download just begun?
}

W3C spec for the WebSocket API 表示应该在“收到 WebSocket 消息时”发送 message 事件:

When a WebSocket message has been received with type type and data data, the user agent must queue a task to follow these steps:

...

  1. Let event be an event that uses the MessageEvent interface, with the event type message, which does not bubble, is not cancelable, and has no default action.

...

  1. Dispatch event at the WebSocket object.

要了解“收到 WebSocket 消息时”的含义,我们必须参考 RFC 6455, "The WebSocket Protocol"。在 WebSockets 中,参与者发送包含在一个或多个 :

中的 消息

After a successful handshake, clients and servers transfer data back and forth in conceptual units referred to in this specification as "messages". On the wire, a message is composed of one or more frames.

一旦你明白了,你就可以理解section 6 of RFC 6455,它定义了短语“WebSocket Message Has Been Received”:

If the frame comprises an unfragmented message (Section 5.4), it is said that _A WebSocket Message Has Been Received_ with type /type/ and data /data/. If the frame is part of a fragmented message, the "Application data" of the subsequent data frames is concatenated to form the /data/. When the last fragment is received as indicated by the FIN bit (frame-fin), it is said that _A WebSocket Message Has Been Received_ with data /data/...

假设服务器端库的 send 方法将其参数视为“消息”,规范要求客户端在触发 message 事件之前等待收到整个消息。

允许流式传输的服务器端 API(例如,它保持消息不完整并保留 FIN 位,直到调用某种 finish 方法)不会导致客户端触发message 事件直到消息结束。