typescript
33 lines · 1 tab
Mateo Rodriguez
Jan 2026
1 tab
import { WebSocketServer } from 'ws';
import type WebSocket from 'ws';
type ClientState = { topics: Set<string> };
const state = new WeakMap<WebSocket, ClientState>();
export function startWsServer(server: import('node:http').Server) {
const wss = new WebSocketServer({ server, maxPayload: 1024 * 64 });
wss.on('connection', (socket) => {
state.set(socket, { topics: new Set() });
socket.on('message', (buf) => {
const msg = JSON.parse(buf.toString('utf8')) as { type: string; topic?: string };
const s = state.get(socket)!;
if (msg.type === 'subscribe' && msg.topic) s.topics.add(msg.topic);
if (msg.type === 'unsubscribe' && msg.topic) s.topics.delete(msg.topic);
});
});
return {
publish(topic: string, data: unknown) {
const payload = JSON.stringify({ type: 'event', topic, data });
for (const client of wss.clients) {
const s = state.get(client);
if (s?.topics.has(topic) && client.readyState === client.OPEN) {
client.send(payload);
}
}
}
};
}
1 file · typescript
Explain with highlit
Raw WebSockets can turn into an unmaintainable mess unless you define a tiny protocol up front. I keep messages typed (even if it’s ‘JSON with a type field’) and I implement topic subscriptions so clients opt into exactly what they need. I track subscriptions per connection and clean them up on close so state doesn’t leak. Another practical detail is defensive limits: set maxPayload and validate incoming payloads so one bad client can’t chew CPU and memory. For many apps I’ll start with SSE, but when I truly need bidirectional real-time interactions, a topic-based approach keeps the system sane as features grow.
Related snips
typescript
export type Settled<R> =
| { status: 'fulfilled'; value: R }
| { status: 'rejected'; reason: unknown };
export interface ConcurrencyOptions {
limit: number;
Simple concurrency limiter for batch operations
node
concurrency
async
by codesnips
2 tabs
typescript
import { randomBytes, createHash } from "crypto";
import jwt from "jsonwebtoken";
import { RefreshTokenStore } from "./store";
const ACCESS_SECRET = process.env.ACCESS_SECRET!;
const ACCESS_TTL = "15m";
JWT access + refresh token rotation (conceptual)
security
node
jwt
by codesnips
3 tabs
ruby
class Comment < ApplicationRecord
belongs_to :article
belongs_to :author, class_name: "User"
validates :body, presence: true, length: { maximum: 2_000 }
Live comments with model broadcasts + turbo_stream_from
rails
hotwire
turbo
by codesnips
4 tabs
erb
<%# private stream: turbo signs the serialized record name %>
<%= turbo_stream_from current_user %>
<section class="notifications">
<h1>Notifications</h1>
Turbo Streams + authorization: signed per-user stream name
rails
turbo
hotwire
by codesnips
3 tabs
ruby
# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
def subscribed
# Subscribe to a specific room
room = Room.find(params[:room_id])
ActionCable for real-time WebSocket communication
ruby
rails
actioncable
by Sarah Mitchell
3 tabs
sql
CREATE TABLE outbox (
id BIGSERIAL PRIMARY KEY,
aggregate_type TEXT NOT NULL,
aggregate_id TEXT NOT NULL,
event_type TEXT NOT NULL,
payload JSONB NOT NULL,
Transactional outbox in Node (DB write + event)
node
postgres
reliability
by codesnips
3 tabs
Share this code
Here's the card — post it anywhere.