-
-
Notifications
You must be signed in to change notification settings - Fork 53
Broadcast
- You want to send a message to every connection on the server.
- You want to send a message to a subset (a room, a namespace, or "every client except the sender").
- You want to send a message to a specific connection by ID.
Neffos broadcasting is non-blocking by default: a slow client never holds up new connections or other broadcasts. This is a significant departure from naive "iterate the connection list under a lock" schemes.
A client never talks directly to another client. All traffic goes through the server, so the server is the only broadcaster. Two layers of helpers:
| API | Use when |
|---|---|
NSConn.Broadcast(...) / NSConn.BroadcastOthers(...)
|
You are inside an event callback and have the NSConn. Most common. |
Server.Broadcast(exceptSender, msgs...) |
You don't have an NSConn — for example, in an HTTP handler that fires a notification, or in a background goroutine. |
The recommended path. The new helpers in NSConn (Broadcast and BroadcastOthers) replace the older c.Conn.Server().Broadcast(c, msg) chain:
neffos.Events{
"chat": func(c *neffos.NSConn, msg neffos.Message) error {
// Echo the message to everyone EXCEPT the sender.
c.BroadcastOthers(msg)
return nil
},
}Broadcast sends to everyone including the sender; BroadcastOthers excludes the current connection. Both are server-side only — calling them on a client-side NSConn panics with a nil-pointer dereference.
When you don't have an NSConn (background job, HTTP handler, signal handler), use Server.Broadcast:
// websocketServer := neffos.New(...)
websocketServer.Broadcast(nil, neffos.Message{
Namespace: "default",
Event: "system.notice",
Body: []byte("scheduled maintenance in 5 minutes"),
})The first parameter is the exceptSender. Pass nil to broadcast to everyone, or any value that satisfies fmt.Stringer:
-
*neffos.Conn(the sender's connection) -
*neffos.NSConn(the sender's namespaced connection) -
*neffos.Room(the sender's room) -
neffos.Exclude("connection-id")if you only have the string ID
To send a message to one connection by ID, fill Message.To:
websocketServer.Broadcast(nil, neffos.Message{
Namespace: "default",
Event: "notification",
Body: []byte("you've got mail"),
To: "user-42",
})The Namespace and Room checks still apply: the target connection must be connected to the namespace (and joined to the room, if Room is set).
Fill Message.Room to deliver to every connection joined to that room within the namespace:
websocketServer.Broadcast(nil, neffos.Message{
Namespace: "default",
Room: "lobby",
Event: "chat",
Body: []byte("welcome!"),
})When called from an event callback, the NSConn helpers stay shorter:
c.BroadcastOthers(neffos.Message{
Room: "lobby",
Event: "chat",
Body: []byte("welcome!"),
})(Namespace is filled automatically from the NSConn.)
- At-most-once. If a connection's outbox is saturated or the connection is mid-close, that connection silently drops the message. There is no per-message ack. If you need delivery confirmation, use The ask method instead.
-
Non-blocking.
Server.Broadcastreturns immediately. Slow consumers never block accepts or other broadcasts. -
Order is per-receiver, not global. Two
Broadcastcalls A then B will each arrive at each receiver in order A→B, but two receivers may see them at different times.
If you need strict ordering at the cost of throughput (no in-flight overlap), set Server.SyncBroadcaster = true before clients connect:
ws := neffos.New(upgrader, handler)
ws.SyncBroadcaster = trueWhen a StackExchange is configured (Redis / NATS) this flag is ignored — the backend already serializes order.
Broadcast only sends messages. To run arbitrary code on every connection (close them, increment counters, gather state), use Server.Do:
// Force-disconnect everyone from the "default" namespace.
websocketServer.Do(func(c *neffos.Conn) {
c.Namespace("default").Disconnect(context.Background())
}, false)
log.Printf("%d clients disconnected", websocketServer.GetTotalConnections())
Server.GetTotalConnections()is an atomic read and cheap.
Or to terminate every connection entirely:
websocketServer.Do(func(c *neffos.Conn) {
c.Close()
}, false)Important: Server.Do runs on the server's dispatch goroutine. Long work inside fn delays accepting new connections and processing disconnects. Pass async = true if you need fire-and-forget.
- Namespaces and Rooms — to scope your broadcasts
- The ask method — when you need a reply
- Scale out — broadcasting across multiple neffos instances
Home | About | Project | Getting Started | Technical Docs | Copyright © 2019-2023 Gerasimos Maropoulos. Documentation terms of use.
Getting started
Concepts
Messaging
Production
Scale out