← All projects

Case · Go backend

Rooms: realtime chat and board

Realtime rooms: chat with SQLite history, an online list, a typing indicator, a shared board with strokes and cursors, anonymous nicknames. WebSocket (RFC 6455) written on the stdlib.

  • Go
  • WebSocket
  • SQLite
  • Canvas
  • Docker

01 · How it looks

Screenshots

Screenshot of the project "Rooms: realtime chat and board" at 1280 pixels wide
Desktop, 1280 px
Screenshot of the project "Rooms: realtime chat and board" on a phone screen, 390 pixels wide
Phone, 390 px

02 · About

What it is and why

Realtime rooms: a chat with history in SQLite, an online list, a typing indicator and a shared board where every participant's strokes and cursors are visible to everyone at once. No sign-up; nicknames are anonymous.

The WebSocket protocol (RFC 6455) is written on the standard library: handshake, frames, masking, fragmentation, ping/pong and close codes. The only dependency is pure-Go SQLite without CGO; the vanilla JS and Canvas interface is embedded in the binary.

Limitations

A single process with the hub in memory, so there is no horizontal scaling. The board lives in memory and does not survive a server restart (the chat is saved in SQLite).

No TLS or authentication, and nicknames are anonymous and unprotected. There is no permessage-deflate; the Autobahn Test Suite was not run, and correctness is covered by my own tests.

The bot in the demo room answers with canned phrases and is marked as a bot: it is neither a person nor an AI.

What is inside

  • Room hub: two goroutines per connection, broadcasting through a bounded queue; a slow client is disconnected and does not hold the others back
  • Per-connection rate limits (a token bucket for chat and an overall one); ephemeral messages (cursors, typing) are dropped under load
  • Chat history in SQLite: a message is broadcast only after it is saved, the last 50 are sent on join and older ones load page by page
  • A shared Canvas board: strokes in normalised coordinates, other people's cursors with nicknames, and the current state is sent to late joiners
  • Graceful shutdown: every connection gets close code 1001; the browser reconnects with exponential backoff and jitter
  • Protocol and hub tests, a load test with 360 connections in 6 rooms; Docker and GitHub Actions

03 · How to run

Run it locally

git clone <repository on request> realtime-rooms
cd realtime-rooms
SEED_DEMO=1 go run ./cmd/server   # http://localhost:8086, room /r/demo

04 · Code

The repository is private

The source lives in a private repository. I will grant access on request: write to me and I will send an invitation.

Request the code