Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is WebSocket.onmessage triggered?

(1) Open a WebSocket connection.

var ws = new WebSocket(url);

(2) When connection is established, send a message which will trigger a blob sent back in response.

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

(3) Is onmessage triggered when the response begins or is complete?

ws.onmessage = function () {
    // Has the entire blob arrived or has the download just begun?
}
like image 606
Derek Henderson Avatar asked Sep 28 '22 19:09

Derek Henderson


1 Answers

The W3C spec for the WebSocket API says that a message event should be dispatched "when a WebSocket message has been received":

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.

To understand what is meant by "when a WebSocket message has been received," we must consult RFC 6455, "The WebSocket Protocol". In WebSockets, participants send messages that are contained in one or more frames:

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.

Once you understand that, you can understand section 6 of RFC 6455, which defines the phrase "A 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/...

Assuming that sever-side library's send method treats its argument as a "message", the specification requires that the client wait for the receipt of the entire message before firing the message event.

A server-side API that allowed streaming (e.g., it kept the message incomplete and withheld the FIN bit until some kind of finish method was called) would not cause the client to fire the message event until the message concluded.

like image 111
apsillers Avatar answered Oct 01 '22 15:10

apsillers