Implementing Pub/Sub Pattern

1. Understanding Publish-Subscribe Pattern

Publishers emit messages to topics; subscribers receive matching messages without direct coupling. WebSocket commonly carries the client side over a broker (Redis, NATS, Kafka).

RoleAction
PublisherSend to topic
BrokerFan-out
SubscriberReceive matching
TopicRouting key (e.g. orders.*)

2. Implementing Topic Subscription

Example: Subscribe / unsubscribe

ws.send(JSON.stringify({ "type": "sub", "topic": "prices.BTC" }));
ws.send(JSON.stringify({ "type": "unsub", "topic": "prices.BTC" }));
MessageServer Action
subAdd to topic subscriber list
unsubRemove from list
listReturn current subs

3. Managing Subscriber Lists

StructureUse
Map<topic, Set<WebSocket>>Direct fan-out
Map<WebSocket, Set<topic>>Cleanup on disconnect
TrieWildcard matching
Redis SET / Pub-SubMulti-node

4. Publishing Messages to Topics

Example: Publish helper

function publish(topic, payload) {
  const subs = topics.get(topic);
  if (!subs) return;
  const msg = JSON.stringify({ "type":"msg", "topic":topic, "payload":payload });
  for (const c of subs) if (c.readyState === 1) c.send(msg);
}

5. Implementing Topic Wildcards

ConventionMatch
* (single segment)orders.*orders.new
# (multi segment)orders.#orders.eu.new
:paramNamed capture (custom)

6. Handling Private Channels

TypeAccess
PublicAnyone may subscribe
Private (private- prefix)Auth required
PresenceAuth + member list
EncryptedEnd-to-end key per channel

7. Implementing Message Filtering

Example: Predicate filter

// per-subscriber filter
function publishFiltered(topic, payload) {
  for (const c of topics.get(topic) ?? []) {
    if (c.filter?.(payload) ?? true) c.send(JSON.stringify(payload));
  }
}
FilterUse
Field predicate{ "sym":"BTC", "px>":50000 }
Geo filterBounding box / radius
Permission filterHide fields user can't read

8. Managing Subscription State

StateDetail
Persist on reconnectResubscribe from client
Server snapshotSend initial state on subscribe
Last seqResume from gap

9. Implementing Presence

Example: Presence events

{ "type": "presence.join", "topic": "room-42", "user": { "id": "u1", "name": "Ada" } }
{ "type": "presence.leave", "topic": "room-42", "user": { "id": "u1" } }
{ "type": "presence.list",  "topic": "room-42", "users": [ /* ... */ ] }
EventTrigger
joinSubscriber added
leaveSubscriber removed/disconnected
updateMetadata change
syncPeriodic full state

10. Handling Subscription Limits

LimitDetail
Max topics / connectione.g. 100
Max subscribers / topice.g. 10k (fan-out cost)
Rate of sub/unsubToken bucket
Wildcard depthCap to prevent explosions