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.

HeaderDirection
Client: Sec-WebSocket-Protocol: a, b, cPreferred order
Server: Sec-WebSocket-Protocol: bPicked 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;
  }
});
ReturnEffect
StringSelected protocol
falseNone selected (header omitted)

3. Specifying Client Subprotocols

Example: Multiple candidates

const ws = new WebSocket("wss://x/", ["chat.v2","chat.v1"]);
FormNotes
Single stringOne protocol only
ArrayPreferred order
ABNF tokenNo commas/whitespace in name

4. Selecting Server Subprotocol

StrategyUse
Highest supportedLatest version wins
Client preferenceFirst match
Feature-flaggedBased on user/tenant

5. Accessing Active Subprotocol

Example: Branch on protocol

ws.addEventListener("open", () => {
  if (ws.protocol === "chat.v2") useV2();
  else useV1();
});
PropertyValue
ws.protocolNegotiated, or ""

6. Implementing Custom Protocol

Naming ConventionExample
vendor.name.versionacme.chat.v2
Reverse-DNScom.example.chat
IANA-registeredmqtt, soap

7. Using Standard Subprotocols

SubprotocolUse
mqttMQTT over WS
graphql-transport-wsModern GraphQL subscriptions
graphql-wsLegacy (Apollo) DEPRECATED
wamp.2.jsonWAMP RPC/PubSub
v10.stompSTOMP over WS

8. Handling Protocol Mismatch

Example: Reject on mismatch

ws.addEventListener("open", () => {
  if (!ws.protocol) ws.close(4000, "no-subprotocol-agreed");
});
StrategyDetail
Close 1002/4000Hard fail
Fallback to defaultContinue with assumed protocol

9. Versioning Subprotocols

PatternDetail
Suffix .vNBreaking changes bump N
Negotiate downServer supports last 2 versions
Sunset headerAnnounce deprecation date

10. Documenting Protocol Specification

SectionContents
HandshakeRequired headers, status codes
Message typesJSON schema per type
LifecycleAuth, subscribe, close
Error codesApp-level 4xxx mapping
CompatibilityVersion matrix