WebSocket subprotocols

This might be a bug: Deno's websocket implementation seems to have issues with subprotocols (RFC section on subprotocol). I was using one initially, then I removed it and that issue seems to be resolved.

With the subprotocol, since the one returned by
Deno.upgradeWebSocket
does not include the
sec-websocket-protocol
header, and response headers are immutable, I was instantiating a new
Response
instance, copying over data from the response returned by upgradeWebSocket and adding the sec-websocket-protocol header. Even then, the websocket in Deno never opened and all of its properties including
readyState
would remain undefined indefinitely.

The browser was happy, though: its websocket instance's open event was firing, only the server never could use its websocket instance. I removed the subprotocols parameter to the websocket constructor and the code on the server handing it and now the server's websocket is opening and messages are flowing.

server:
import { serve } from "http";

serve((request) => {
  if (request.headers.get("sec-websocket-protocol") === "esm-hmr") {
    const { socket, response } = Deno.upgradeWebSocket(request);
    // <Do stuff with socket>

    // Create new response with proper headers
    return new Response(null, {
      status: response.status,
      statusText: response.statusText,
      headers: {
        connection: response.headers.get("connection")!,
        "sec-websocket-accept": response.headers.get("sec-websocket-accept")!,
        upgrade: response.headers.get("upgrade")!,
        "sec-websocket-protocol": "esm-hmr"
      }
    })
  } else {
    return new BadRequestResponse()
  }
})


client:
const socket = new WebSocket(socketURL, "esm-hmr");
Was this page helpful?