C.W.K.
Stream
Lesson 01 of 08 · published

Creating a Connection

~12 min · browser, constructor

Level 0Poller
0 XP0/60 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

One line opens the door

The browser's WebSocket constructor is shockingly small. new WebSocket(url) immediately begins the upgrade handshake; the constructor returns synchronously while the connection negotiates in the background. Until the open event fires, you cannot send anything — but the object exists and you can attach listeners.

Subprotocols

The optional second argument is a string or array of subprotocol names. The server picks one (or rejects all) during the handshake. graphql-ws, graphql-transport-ws, and mqtt are common in the wild. After open, ws.protocol tells you which one the server accepted.

Auth in the URL

The native WebSocket constructor does not let you set custom HTTP headers — there is no equivalent of fetch options. So most teams pass authentication tokens as URL query parameters. This is fine for wss:// (the URL is encrypted on the wire) but be aware that query strings often land in server access logs, so do not pass long-lived secrets — pass short-lived signed tokens.

Code

Constructor variants·javascript
// Plain
const ws = new WebSocket('ws://localhost:8000/ws');

// TLS for production
const wss = new WebSocket('wss://api.example.com/ws');

// With auth token in the query string
const auth = new WebSocket(
  'wss://api.example.com/ws?token=' + encodeURIComponent(jwt)
);

// Subprotocol negotiation
const sub = new WebSocket(
  'wss://api.example.com/ws',
  ['graphql-transport-ws', 'graphql-ws']
);
sub.addEventListener('open', () => {
  console.log('server picked:', sub.protocol);
});
readyState transitions·javascript
const ws = new WebSocket('ws://localhost:8000/ws');

console.log(ws.readyState); // 0 (CONNECTING) — synchronous return

ws.addEventListener('open', () => {
  console.log(ws.readyState);  // 1 (OPEN)
  console.log(ws.protocol);    // selected subprotocol or ''
  console.log(ws.url);         // 'ws://localhost:8000/ws'
  console.log(ws.extensions);  // negotiated extensions or ''
});

External links

Exercise

Open wss://echo.websocket.org/ (or any echo service) in devtools. Construct a WebSocket and log readyState immediately, then again inside an open handler, then again 100ms after open. Confirm the synchronous-vs-async transition. Now try connecting to a non-existent path on a real server — observe how readyState jumps from 0 to 3 without ever passing through 1.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.