Documentation
¶
Index ¶
Constants ¶
const ( TypeJoin = "join" TypeLeave = "leave" TypeSend = "send" TypeTypingStart = "typing_start" TypeTypingStop = "typing_stop" TypePing = "ping" )
Inbound frame types.
const ( TypeAck = "ack" TypeError = "error" TypePresenceUpdate = "presence_update" TypeTypingUpdate = "typing_update" TypePong = "pong" )
Outbound frame types.
Variables ¶
This section is empty.
Functions ¶
func NewConnection ¶
func NewConnection(conn *websocket.Conn, id Identity, validate func(string) (string, error), registry *room.Registry) actor.Producer
NewConnection returns a Producer for a connection actor bound to conn. validate is the server's JWT check (passed as a func to keep this package free of an import on the server package); id was already established at upgrade.
Types ¶
type Connection ¶
type Connection struct {
// contains filtered or unexported fields
}
Connection is the actor owning one WebSocket connection (PRD §9). All writes to the socket go through its mailbox, so they are serialized; reads happen in ReadLoop on the HTTP handler goroutine and are forwarded here as Frame messages.
id.Token is a lease: Clerk JWTs expire in ~60s while connections live for hours, so the client mails a fresh one on each ping and the actor swaps its private copy. No shared state, no locks — renewal is just a message.
func (*Connection) Receive ¶
func (cn *Connection) Receive(c *actor.Context)
type Frame ¶
type Frame struct {
Type string `json:"type"`
// Common
RoomID string `json:"roomId,omitempty"`
UserID string `json:"userId,omitempty"`
// send / ack / error
Body string `json:"body,omitempty"`
ClientID string `json:"clientId,omitempty"`
MessageID string `json:"messageId,omitempty"`
CreatedAt float64 `json:"createdAt,omitempty"`
Reason string `json:"reason,omitempty"`
// presence_update: full set of online userIds in the room
Users []string `json:"users,omitempty"`
// typing_update
Typing bool `json:"typing,omitempty"`
// ping: optional fresh JWT so long-lived connections outlive the ~60s
// token lifetime (PRD §13). Never sent by the server.
Token string `json:"token,omitempty"`
}
Frame is the JSON envelope for every message on the app WebSocket (PRD §11). One struct covers both directions; unused fields are omitted.
Inbound types: join, leave, send, typing_start, typing_stop, ping Outbound types: ack, error, presence_update, typing_update, pong
type Identity ¶
type Identity struct {
UserID string // Convex users._id
AuthID string // Clerk JWT subject
Token string // current JWT lease
}
Identity is what the upgrade handler established about the peer. AuthID is the fixed proof of who they are — token refreshes must present the same Clerk sub — while UserID is the public identity others render (presence and typing key off users._id). Token is the current JWT lease, swapped on each ping refresh.