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

Closing Connections

~10 min · browser, close-codes

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

close(code, reason)

Calling ws.close() initiates the close handshake — the browser sends a close frame, the server responds with one, and the underlying TCP socket tears down. You can pass an optional close code and reason. The reason is a UTF-8 string, max 123 bytes — long enough for "session expired", short enough to keep the close frame compact.

Application close codes (4000-4999)

The 4000-4999 range is reserved for application-defined codes. Pick a few stable ones for your protocol — 4001 unauthorized, 4029 too many connections, 4040 room not found — and your client can branch on them cleanly. Avoid using 1xxx codes like 1001 or 1011 from application logic; those have RFC meaning.

wasClean tells you the truth

The close event has a wasClean boolean. true means a proper close handshake completed; the code is meaningful. false means the connection died — the code will usually be 1006 and the reason will be empty.

Code

Close with reason·javascript
// Normal user-initiated logout
ws.close(1000, 'user logged out');

// Application-defined: "your token has expired"
ws.close(4001, 'token expired');

// React to close codes on the listener side
ws.addEventListener('close', (e) => {
  if (!e.wasClean) {
    console.warn('connection lost — schedule reconnect');
    return scheduleReconnect();
  }
  switch (e.code) {
    case 1000: return console.log('clean close');
    case 1001: return console.log('server going away');
    case 4001: return redirectToLogin();
    case 4029: return showRateLimitToast();
    default:   return console.warn('unexpected close', e.code, e.reason);
  }
});

External links

Exercise

Define a five-row close-code table for an imaginary chat app: 1000 normal, 4001 unauthorized, 4029 rate limited, 4040 room not found, 4503 server overloaded. Implement a switch on the client that produces a different toast for each. Trigger each one from the server side and verify the UI reacts correctly.

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.