Working with Subprotocols
1. Understanding Subprotocols
A subprotocol is a named application-layer protocol negotiated via the Sec-WebSocket-Protocol header. The server picks one (or none) from the client's preference list.
| Header | Direction |
|---|---|
Client: Sec-WebSocket-Protocol: a, b, c | Preferred order |
Server: Sec-WebSocket-Protocol: b | Picked one |
2. Negotiating Subprotocol
Example: Server selector
new WebSocketServer({
port: 8080,
handleProtocols: (protocols, req) => {
const supported = ["chat.v2","chat.v1"];
return supported.find(p => protocols.has(p)) || false;
}
});
| Return | Effect |
|---|---|
| String | Selected protocol |
false | None selected (header omitted) |
3. Specifying Client Subprotocols
| Form | Notes |
|---|---|
| Single string | One protocol only |
| Array | Preferred order |
| ABNF token | No commas/whitespace in name |
4. Selecting Server Subprotocol
| Strategy | Use |
|---|---|
| Highest supported | Latest version wins |
| Client preference | First match |
| Feature-flagged | Based on user/tenant |
5. Accessing Active Subprotocol
Example: Branch on protocol
ws.addEventListener("open", () => {
if (ws.protocol === "chat.v2") useV2();
else useV1();
});
| Property | Value |
|---|---|
ws.protocol | Negotiated, or "" |
6. Implementing Custom Protocol
| Naming Convention | Example |
|---|---|
| vendor.name.version | acme.chat.v2 |
| Reverse-DNS | com.example.chat |
| IANA-registered | mqtt, soap |
7. Using Standard Subprotocols
| Subprotocol | Use |
|---|---|
mqtt | MQTT over WS |
graphql-transport-ws | Modern GraphQL subscriptions |
graphql-ws | Legacy (Apollo) DEPRECATED |
wamp.2.json | WAMP RPC/PubSub |
v10.stomp | STOMP over WS |
8. Handling Protocol Mismatch
Example: Reject on mismatch
ws.addEventListener("open", () => {
if (!ws.protocol) ws.close(4000, "no-subprotocol-agreed");
});
| Strategy | Detail |
|---|---|
| Close 1002/4000 | Hard fail |
| Fallback to default | Continue with assumed protocol |
9. Versioning Subprotocols
| Pattern | Detail |
|---|---|
Suffix .vN | Breaking changes bump N |
| Negotiate down | Server supports last 2 versions |
| Sunset header | Announce deprecation date |
10. Documenting Protocol Specification
| Section | Contents |
|---|---|
| Handshake | Required headers, status codes |
| Message types | JSON schema per type |
| Lifecycle | Auth, subscribe, close |
| Error codes | App-level 4xxx mapping |
| Compatibility | Version matrix |