Documentation
¶
Overview ¶
Package rtcstats collects the WebRTC trace events the SDK reports to the SFU.
The emitted format is part of the SFU wire protocol: a TraceBuffer holds one JSON array per event, `[eventName, pcID, payload, epochMillis]`, and the drained lines are spliced into the RtcStats field of the SFU's SendStats RPC. Changing the tuple layout, the event names or the pcID format breaks the server-side parser, so treat all of it as protocol rather than as internal detail.
Index ¶
Constants ¶
const ( GetStatsEvent = "getstats" SignalRPCSetPublisherEvent = "signal.rpc.setpublisher" SignalRPCSetPublisherResponseEvent = "signal.rpc.setpublisher.response" SignalRPCSendAnswerEvent = "signal.rpc.sendanswer" SignalRPCSendAnswerResponseEvent = "signal.rpc.sendanswer.response" SignalRPCIceTrickleEvent = "signal.rpc.icetrickle" SignalRPCUpdateSubscriptionsEvent = "signal.rpc.updatesubscriptions" SignalRPCUpdateSubscriptionsResponseEvent = "signal.rpc.updatesubscriptions.response" SignalRPCUpdateMuteStatesEvent = "signal.rpc.updatemutestates" SignalRPCIceRestartEvent = "signal.rpc.icerestart" SignalRPCStartNoiseCancellationEvent = "signal.rpc.startnoisecancellation" SignalRPCStopNoiseCancellationEvent = "signal.rpc.stopnoisecancellation" SignalWSOpenEvent = "signal.ws.open" SignalWSJoinRequestEvent = "signal.ws.joinrequest" SignalWSJoinResponseEvent = "signal.ws.joinresponse" SignalWSErrorEvent = "signal.ws.error" SignalWSCallEndedEvent = "signal.ws.callended" SignalWSCallGrantsUpdatedEvent = "signal.ws.callgrantsupdated" SignalWSGoAwayEvent = "signal.ws.goaway" SignalWSIceRestartEvent = "signal.ws.icerestart" SignalWSSubscriberOfferEvent = "signal.ws.subscriberoffer" SignalWSPublisherAnswerEvent = "signal.ws.publisheranswer" SignalWSConnectionQualityChangedEvent = "signal.ws.connectionqualitychanged" SignalWSIceTrickleEvent = "signal.ws.icetrickle" SignalWSChangePublishQualityEvent = "signal.ws.changepublishquality" SignalWSParticipantJoinedEvent = "signal.ws.participantjoined" SignalWSParticipantLeftEvent = "signal.ws.participantleft" SignalWSTrackPublishedEvent = "signal.ws.trackpublished" SignalWSTrackUnpublishedEvent = "signal.ws.trackunpublished" CoordinatorWSConnectEvent = "coordinator.ws.connect" CoordinatorWSConnectedEvent = "coordinator.ws.connected" CoordinatorJoinCallEvent = "coordinator.joincall" CoordinatorJoinCallResponseEvent = "coordinator.joincall.response" CoordinatorConnectEvent = "coordinator.connect" CoordinatorConnectedEvent = "coordinator.connected" PeerCreateEvent = "create" PeerOnTrackEvent = "ontrack" PeerAddICECandidateEvent = "addicecandidate" PeerAddICECandidateSuccessEvent = "addicecandidatesuccess" PeerConnectionStateChangeEvent = "connectionstatechange" PeerICECandidateEvent = "icecandidate" PeerICEConnectionStateChangeEvent = "iceconnectionstatechange" PeerICEGatheringStateChangeEvent = "icegatheringstatechange" PeerNegotiationNeededEvent = "negotiationneeded" PeerSetLocalDescriptionEvent = "setlocaldescription" PeerSetLocalDescriptionSuccessEvent = "setlocaldescriptionsuccess" PeerSetRemoteDescriptionEvent = "setremotedescription" PeerSetRemoteDescriptionSuccessEvent = "setremotedescriptionsuccess" PeerSignalingStateChangeEvent = "signalingstatechange" RembBitrateChangeEvent = "remb_bitrate_change" TrackMappingEvent = "track.mapping" )
Event names. These strings are matched by the SFU and by the rtcstats viewer; do not rename them.
Variables ¶
This section is empty.
Functions ¶
func DeltaCompressionRtcStats ¶
DeltaCompressionRtcStats strips from newStats every field that is unchanged from oldStats, deletes the per-report "id" (it is the map key already) and hoists the largest report timestamp to newStats["timestamp"], zeroing the per-report copies of it. Both maps must be the JSON-decoded form of a getStats report, i.e. map[reportID]map[string]any.
Types ¶
type StatsEvent ¶
type StatsEvent struct {
Timestamp float64 `json:"timestamp"` // µs
Raw json.RawMessage `json:"-"`
}
type TraceBuffer ¶
type TraceBuffer struct {
// contains filtered or unexported fields
}
TraceBuffer accumulates trace events for one namespace and peer connection. It is safe for concurrent use, and every method tolerates a nil receiver so callers can emit unconditionally.
func NewCallTraceBuffer ¶
func NewCallTraceBuffer(ns string, version int64, sfuID string) *TraceBuffer
NewCallTraceBuffer returns a buffer for call-scoped events, tagged "<version+1>-<sfuID>".
func NewClientTraceBuffer ¶
func NewClientTraceBuffer(ns string) *TraceBuffer
NewClientTraceBuffer returns a buffer for client-scoped events, which carry no peer-connection ID.
func NewPubTraceBuffer ¶
func NewPubTraceBuffer(ns string, version int64, sfuID string) *TraceBuffer
NewPubTraceBuffer returns a buffer for publisher events, tagged "pub-<version+1>-<sfuID>".
func NewSubTraceBuffer ¶
func NewSubTraceBuffer(ns string, version int64, sfuID string) *TraceBuffer
NewSubTraceBuffer returns a buffer for subscriber events, tagged "sub-<version+1>-<sfuID>".
func (*TraceBuffer) Drain ¶
func (tb *TraceBuffer) Drain() []byte
Drain returns all queued lines (chronologically sorted) and resets the buffer. Lines are newline separated with a trailing newline.
func (*TraceBuffer) DrainWithComma ¶
func (tb *TraceBuffer) DrainWithComma(trailing bool) []byte
DrainWithComma returns all queued lines comma separated, optionally with a trailing comma. This is what the SDK uses to splice several buffers into one JSON array for the SendStats RPC.
func (*TraceBuffer) Emit ¶
func (tb *TraceBuffer) Emit(event string, payload any)
Emit queues `[event, pcID|null, payload, epochMs]` in a thread-safe way.
type TraceEvent ¶
type TraceEvent struct {
Type string // column 0
PCID *string // column 1 – may be nil
Value json.RawMessage // column 2
Timestamp int64 // column 3 (ms)
Raw json.RawMessage // original line
}
TraceEvent is the decoded form of one emitted tuple. It is not produced by this package; it documents the layout consumers parse back out.