Realtime Presence

Track who is online in real-time across channels using Nimbus Presence over WebSockets. Great for chat rooms, collaboration, and live dashboards.

Setup

import "github.com/CodeSyncr/nimbus/presence"

hub := presence.NewHub(presence.Config{
    Path:          "/_presence",
    PingInterval:  30 * time.Second,
    WriteTimeout:  10 * time.Second,
    MaxMessageSize: 4096,
    AllowedOrigins: []string{"https://app.example.com"},
    AuthFunc: func(r *http.Request, channel string) (*presence.User, error) {
        // Resolve authenticated user for this channel.
        return &presence.User{ID: "123", Name: "Yash"}, nil
    },
})

app.Use(presence.NewPlugin(presence.Config{
    Path:          "/_presence",
    PingInterval:  30 * time.Second,
    WriteTimeout:  10 * time.Second,
    MaxMessageSize: 4096,
    AllowedOrigins: []string{"https://app.example.com"},
    AuthFunc: func(r *http.Request, channel string) (*presence.User, error) {
        return &presence.User{ID: "123", Name: "Yash"}, nil
    },
}))

API

// Hub helpers
channels := hub.Channels()
count := hub.UserCount("room-1")
users := hub.UsersIn("room-1")

// Server-side broadcast into a channel
hub.Broadcast("room-1", presence.Event{
    Type: "message",
    Data: "hello from server",
})

// Plugin routes mounted automatically:
// GET /_presence?channel=room-1   (WebSocket endpoint)
// GET /_presence/channels         (list channels)
// GET /_presence/channels/:name/users
// POST /_presence/channels/:name/broadcast

Use Cases

Use CaseChannel PatternDescription
Chat roomschat:{room}Show who's in a chat room
Collaborationdoc:{id}Show who's editing a document
Gaminggame:{lobby}Track players in a game lobby
Live dashboardsdashboard:{id}Show active viewers

Client example

const ws = new WebSocket("ws://localhost:3333/_presence?channel=room-1");

ws.onmessage = (e) => {
  const evt = JSON.parse(e.data);
  // presence:join, presence:leave, presence:state, presence:typing, message, ...
  console.log(evt.type, evt);
};

// typing indicator
ws.send(JSON.stringify({ type: "typing", data: { typing: true } }));

// message event
ws.send(JSON.stringify({ type: "message", data: "hello room" }));

Best Practices

  • Use AuthFunc to authorize channel access per request
  • Set AllowedOrigins explicitly for production deployments
  • Keep channel names scoped (chat:, doc:, game:)
  • Set sane PingInterval and WriteTimeout for your network profile