v154 · network · websockets
An options bag for the WebSocket constructor
The WebSocket constructor has taken exactly two positional arguments since 2011, the second being subprotocols. Chrome 154 accepts a WebSocketInit dictionary instead — { protocols: […] } today, and a place to put everything else that was never addable before.
concepts
-
Both forms, one server
Open real connections to a same-origin echo endpoint using the positional argument and the options bag, and compare what each negotiated. The server reports what it was offered, so the equivalence is confirmed from both ends rather than assumed.
-
Subprotocol negotiation
What actually happens when you offer several protocols, offer one the server does not know, or offer none. The server here picks by its own preference order, which is the rule — the client's order is a list of what it can speak, not a ranking.
-
Why a dictionary at all
The argument for the shape. A positional API cannot grow: every new option would be another argument in a fixed order, undetectable and unskippable. This builds the same connection both ways and shows what feature detection looks like for each.
why it shipped
The constructor's shape has been a dead end for a decade. Anything you might want to say when opening a socket — a target address space, headers, a priority — has nowhere to go, because the only extension point is a third positional argument that older browsers would ignore silently and that nothing could feature-detect.
A dictionary fixes both problems at once. Unknown members are ignored by definition, so adding one is safe; and a member's presence can be detected by handing the constructor an object with a getter and seeing whether it is read. The protocols member mirrors the existing argument exactly, so this ships no new behaviour — only a shape that the next feature can extend, which is precisely what targetAddressSpace does in the same release.
the API
// Since 2011, and still valid:
new WebSocket("wss://example.com/socket", "soap");
new WebSocket("wss://example.com/socket", ["soap", "wamp"]);
// Chrome 154:
new WebSocket("wss://example.com/socket", { protocols: ["soap", "wamp"] });
// …which is what makes this possible in the same release:
new WebSocket("wss://router.local/socket", {
protocols: ["echo"],
targetAddressSpace: "local",
});