// Go subscription to CodeB Signal WebSocket events (ops dashboards). // European Digital Identity Wallet-enabled tenants use the same signalling. // [realtime-events-cookbook 2026-07-23] // go get github.com/gorilla/websocket // // Endpoint: wss:///signal.ashx?room=&name= package main import ( "encoding/json" "log" "net/url" "os" "time" "github.com/gorilla/websocket" ) type frame struct { Type string `json:"type"` Message string `json:"message,omitempty"` Mode string `json:"mode,omitempty"` Room string `json:"room,omitempty"` Peer json.RawMessage `json:"peer,omitempty"` } func main() { host := envOr("CODEB_TENANT_HOST", "phone.example.tld") room := envOr("ROOM", "lobby") name := envOr("NAME", "ops-dashboard") u := url.URL{Scheme: "wss", Host: host, Path: "/signal.ashx", RawQuery: "room=" + url.QueryEscape(room) + "&name=" + url.QueryEscape(name)} backoff := time.Second for { c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) if err != nil { log.Printf("[ws] dial: %v; retry in %s", err, backoff) time.Sleep(backoff) if backoff < 30*time.Second { backoff *= 2 } continue } backoff = time.Second log.Printf("[ws] open %s", u.String()) for { _, buf, err := c.ReadMessage() if err != nil { log.Printf("[ws] read: %v", err) break } var f frame if json.Unmarshal(buf, &f) != nil { continue } switch f.Type { case "welcome": log.Printf("[welcome] mode=%s room=%s", f.Mode, f.Room) case "peer-joined": log.Printf("[peer-joined] %s", f.Peer) case "peer-left": log.Printf("[peer-left] %s", f.Peer) case "mode-changed": log.Printf("[mode-changed] mode=%s", f.Mode) case "error": log.Printf("[server error] %s", f.Message) default: log.Printf("[event] %s", f.Type) } } c.Close() } } func envOr(k, d string) string { if v := os.Getenv(k); v != "" { return v } return d }