Pub/Sub
Publish custom named events to a channel. All subscribers receive them in real time. No server code required for basic pub/sub.
Channel naming
Section titled “Channel naming”Use a path with a slash for custom channels. This bypasses ChangeTracker and uses pure WebSocket pub/sub:
const channel = realtime.channel('todos/shared-workspace')// or:const channel = realtime.channel('chat/general')const channel = realtime.channel('game/room-42')Publish an event
Section titled “Publish an event”channel.publish('todo:created', { id: '123', text: 'Buy groceries', done: false,})All other subscribers on todos/shared-workspace receive this event immediately.
Listen for events
Section titled “Listen for events”channel .on('todo:created', ({ data }) => { setTodos(prev => [...prev, data]) }) .on('todo:toggled', ({ data }) => { setTodos(prev => prev.map(t => t.id === data.id ? data : t)) }) .on('todo:deleted', ({ data }) => { setTodos(prev => prev.filter(t => t.id !== data.id)) }) .subscribe()Avoid echo on your own events
Section titled “Avoid echo on your own events”Use a client ID to skip events you published yourself:
const clientId = useRef(Math.random().toString(36).slice(2))
channel.on('todo:created', ({ data, userId }) => { if (userId === clientId.current) return // skip own event setTodos(prev => [...prev, data])})
// Pass your clientId so the server includes it in userIdchannel.publish('todo:created', todo)Persist events for history
Section titled “Persist events for history”Pass { persist: true } to store the message in the database for later retrieval:
channel.publish('message', { text: 'Hello everyone!', userId: user.id,}, { persist: true })Retrieve history with channel.getHistory() — see Message History.
Server-side pub/sub
Section titled “Server-side pub/sub”Your Workers/Node.js server can also publish to channels:
// In your Worker handlersdk.socket.emit('todo:created', newTodo, 'todos/shared-workspace')This is useful when you want to validate or transform data before broadcasting.
Complete example
Section titled “Complete example”import { useAerostack } from '@aerostack/react'
function CollaborativeList() { const { realtime } = useAerostack() const [items, setItems] = useState([]) const myId = useRef(Math.random().toString(36).slice(2)) const channelRef = useRef(null)
useEffect(() => { const ch = realtime.channel('list/shared') channelRef.current = ch
ch .on('item:added', ({ data, userId }) => { if (userId === myId.current) return setItems(prev => [...prev, data]) }) .subscribe()
return () => ch.unsubscribe() }, [realtime])
const addItem = (text) => { const item = { id: Date.now(), text } setItems(prev => [...prev, item]) // optimistic channelRef.current.publish('item:added', item) // broadcast to peers }
return ( <> <button onClick={() => addItem('New item')}>Add</button> <ul>{items.map(i => <li key={i.id}>{i.text}</li>)}</ul> </> )}See the Collaborative Todos example for a complete working implementation with toggle, delete, and presence.