docs: normalize em dash to hyphen in Russian documentation and code comments

This commit is contained in:
zarazaex69
2026-05-24 05:31:55 +03:00
parent 5498f55083
commit 98c6dec4a0
27 changed files with 82 additions and 83 deletions

View File

@@ -127,7 +127,7 @@ cd olcrtc
Введите Room ID:
```
Для **jitsi** полный URL комнаты в формате `https://host/room` (например `https://meet.cryptopro.ru/myroom`). Имя комнаты придумывается на лету, без регистрации. Подойдёт любой публичный или self-hosted Jitsi Meet.
Для **jitsi** - полный URL комнаты в формате `https://host/room` (например `https://meet.cryptopro.ru/myroom`). Имя комнаты придумывается на лету, без регистрации. Подойдёт любой публичный или self-hosted Jitsi Meet.
Для **telemost** и **wbstream** - создай руму через сайт ([telemost](https://telemost.yandex.ru/), [wbstream](https://stream.wb.ru)) и вставь её ID.

View File

@@ -155,7 +155,7 @@ openssl rand -hex 32
### jitsi + datachannel (рекомендуется)
Самый простой способ: используй любой self-hosted или публичный Jitsi Meet инстанс. Регистрация не нужна, имя комнаты выдумывается на лету. По умолчанию в примерах ниже `meet.cryptopro.ru`, но подойдёт любой другой (`meet.jit.si`, свой self-hosted и т.п.).
Самый простой способ: используй любой self-hosted или публичный Jitsi Meet инстанс. Регистрация не нужна, имя комнаты выдумывается на лету. По умолчанию в примерах ниже - `meet.cryptopro.ru`, но подойдёт любой другой (`meet.jit.si`, свой self-hosted и т.п.).
Создай YAML конфиг:
@@ -180,13 +180,13 @@ data: data
./build/olcrtc-linux-amd64 server.yaml
```
Сервер сам присоединится к комнате (в качестве участника без камеры/микрофона) и будет ждать, пока клиент тоже зайдёт. Без второго участника Jicofo не выдаёт session-initiate это особенность Jitsi.
Сервер сам присоединится к комнате (в качестве участника без камеры/микрофона) и будет ждать, пока клиент тоже зайдёт. Без второго участника Jicofo не выдаёт session-initiate - это особенность Jitsi.
### wbstream + vp8channel (альтернатива)
Создай руму через сайт [wbstream](https://stream.wb.ru) и вставь её ID в `room.id`.
`wbstream + datachannel` **не работает** в обычном guest flow WB Stream выдаёт токены с `canPublishData=false`, и DC не маршрутизирует данные. Для обычного использования выбирай `vp8channel`.
`wbstream + datachannel` **не работает** в обычном guest flow - WB Stream выдаёт токены с `canPublishData=false`, и DC не маршрутизирует данные. Для обычного использования выбирай `vp8channel`.
Создай YAML конфиг:

View File

@@ -30,9 +30,9 @@
**Jitsi:** datachannel стабильно проходит - реализован поверх colibri-ws bridge channel и шлёт байты через `EndpointMessage{raw}` broadcast. Подходит для self-hosted и публичных Jitsi Meet инстансов без аутентификации (`https://meet.cryptopro.ru/...`, `https://meet.jit.si/...` и т.п.). Видео-транспорты (vp8channel, seichannel, videochannel) экспонируют sendable VideoTrack через pion PeerConnection после Jingle session-accept, но Jicofo требует дополнительных протокольных шагов (LastN, ReceiverVideoConstraints, source-add) для маршрутизации видео - поэтому они помечены `~` .
**Jitsi + seichannel отдельная оговорка.** SEI NAL-юниты идут пассажиром в H.264 видеопотоке, а Jicofo на self-hosted инстансах (например `meet.cryptopro.ru`) периодически режет/откладывает upstream видео когда ресивера в комнате формально нет - для нас это выглядит как `seichannel ack timeout` при формально живом PeerConnection. В steady-state транспорт работает, но e2e матрица помечает его `Unstable` (флаппит): зелёного и красного результата в CI достаточно, тест suite на этом не валится. Для надёжной передачи данных через jitsi предпочтительнее `datachannel` или `vp8channel`.
**Jitsi + seichannel - отдельная оговорка.** SEI NAL-юниты идут пассажиром в H.264 видеопотоке, а Jicofo на self-hosted инстансах (например `meet.cryptopro.ru`) периодически режет/откладывает upstream видео когда ресивера в комнате формально нет - для нас это выглядит как `seichannel ack timeout` при формально живом PeerConnection. В steady-state транспорт работает, но e2e матрица помечает его `Unstable` (флаппит): зелёного и красного результата в CI достаточно, тест suite на этом не валится. Для надёжной передачи данных через jitsi предпочтительнее `datachannel` или `vp8channel`.
**Рекомендуемая комбинация: `jitsi + datachannel`** стабильно работает на любом self-hosted или публичном Jitsi Meet (например `meet.cryptopro.ru`), не требует регистрации, простая руму создания. Альтернатива: `wbstream + vp8channel` стабильно для коммерческих сценариев, не требует специальных прав.
**Рекомендуемая комбинация: `jitsi + datachannel`** - стабильно работает на любом self-hosted или публичном Jitsi Meet (например `meet.cryptopro.ru`), не требует регистрации, простая руму создания. Альтернатива: `wbstream + vp8channel` - стабильно для коммерческих сценариев, не требует специальных прав.
Скорость по убыванию: `datachannel` > `vp8channel` > `seichannel` > `videochannel`
@@ -191,7 +191,7 @@ transport. Используй одинаковые traffic-настройки н
### wbstream + datachannel (не работает в обычном guest flow)
WB Stream DataChannel **не работает** в обычном guest flow WB Stream выдаёт токены с `canPublishData=false`, и DC не маршрутизирует данные. Этот режим помечен как expected fail в E2E тестах. Для обычного использования выбирай `vp8channel`, `seichannel` или `videochannel`.
WB Stream DataChannel **не работает** в обычном guest flow - WB Stream выдаёт токены с `canPublishData=false`, и DC не маршрутизирует данные. Этот режим помечен как expected fail в E2E тестах. Для обычного использования выбирай `vp8channel`, `seichannel` или `videochannel`.
```yaml
# room ID нужно создать вручную через https://stream.wb.ru

View File

@@ -222,7 +222,7 @@ data: data
olcrtc://jitsi?datachannel@https://meet.cryptopro.ru/myroom#d823fa01cb3e0609b67322f7cf984c4ee2e4ce2e294936fc24ef38c9e59f4799$RU / olc free sub
```
`<RoomID>` для jitsi полный URL комнаты в формате `https://host/room` (или `host/room`). Поддерживается любой self-hosted Jitsi Meet инстанс без аутентификации; для публичных серверов вроде `meet.jit.si` тот же формат.
`<RoomID>` для jitsi - полный URL комнаты в формате `https://host/room` (или `host/room`). Поддерживается любой self-hosted Jitsi Meet инстанс без аутентификации; для публичных серверов вроде `meet.jit.si` тот же формат.
### Эквивалент YAML

View File

@@ -7,7 +7,7 @@
// expressed via the RoomCreator interface.
//
// The "none" auth provider passes a caller-supplied URL+Token through
// unchanged this is the path that sing-box and other downstream consumers
// unchanged - this is the path that sing-box and other downstream consumers
// take when they want to use olcrtc as a generic LiveKit/Goolom/Jitsi
// transport without any service-specific behaviour baked in.
package auth
@@ -30,7 +30,7 @@ var (
//
// URL is the signaling endpoint (e.g. wss://livekit.example/). Token is the
// access token (LiveKit JWT, Goolom session credential, etc). Extra is for
// engine-specific bits that don't fit the common shape engines should not
// engine-specific bits that don't fit the common shape - engines should not
// rely on it being populated unless their paired auth provider documents it.
type Credentials struct {
URL string
@@ -56,7 +56,7 @@ type Provider interface {
// Engine reports which engine this auth provider feeds.
Engine() string
// DefaultServiceURL returns the well-known service URL for this provider
// (e.g. "https://stream.wb.ru"). Returns "" if no default exists in that
// (e.g. "https://stream.wb.ru"). Returns "" if no default exists - in that
// case the caller must supply -url explicitly.
DefaultServiceURL() string
// Issue obtains credentials for the given room.

View File

@@ -3,7 +3,7 @@
//
// Public Jitsi Meet servers do not require authentication for guest access;
// the only "credentials" the engine needs are the host+room pair extracted
// from a user-supplied room URL. This provider does no HTTP at all it just
// from a user-supplied room URL. This provider does no HTTP at all - it just
// parses the URL and forwards host+room to the engine via auth.Credentials.
//
// Supported RoomURL forms:
@@ -14,7 +14,7 @@
//
// Optional URL path prefixes (e.g. "/jitsi") are preserved as part of the
// host when present, so deployments behind a path-mounted reverse proxy work
// transparently the j library accepts any host string the WebSocket dial
// transparently - the j library accepts any host string the WebSocket dial
// can resolve.
package jitsi
@@ -51,7 +51,7 @@ func (Provider) DefaultServiceURL() string { return defaultServiceURL }
//
// The URL field of the returned Credentials carries the Jitsi host (e.g.
// "meet.example.com"); the room name lives in Extra under CredentialKeyRoom.
// Token is unused Jitsi guest access requires no token.
// Token is unused - Jitsi guest access requires no token.
func (Provider) Issue(_ context.Context, cfg auth.Config) (auth.Credentials, error) {
host, room, err := parseRoomURL(cfg.RoomURL)
if err != nil {

View File

@@ -2,8 +2,8 @@
// It fetches the connection metadata (media server URL, peer ID, room ID,
// signing credentials) the Goolom engine needs to join a conference.
//
// Telemost does not expose an API to create rooms they originate in the
// Yandex UI so this provider does not implement auth.RoomCreator.
// Telemost does not expose an API to create rooms - they originate in the
// Yandex UI - so this provider does not implement auth.RoomCreator.
package telemost
import (

View File

@@ -142,7 +142,7 @@ func RunWithReady(ctx context.Context, cfg Config, onReady func()) error {
// (e.g. handshake timeout against a wedged seichannel transport)
// without ever calling Close on the carrier link, leaving our MUC
// presence behind as a ghost participant in the next test that
// joined the same room. shutdown is nil-safe it skips fields
// joined the same room. shutdown is nil-safe - it skips fields
// that bringUpLink hadn't populated yet.
defer c.shutdown()
@@ -204,7 +204,7 @@ func (c *Client) bringUpLink(
}
// Carrier callback fires after the link is back up. If handshake
// still fails it usually means the server hasn't completed its
// own reinstall yet keep the listener up and wait for either
// own reinstall yet - keep the listener up and wait for either
// another callback or a future liveness loss to re-trigger.
c.handleReconnect(ctx, cfg, cancel, "carrier")
})
@@ -287,8 +287,8 @@ func openControlStreamTimeout(
// resolveDeviceID returns the device ID to send in CLIENT_HELLO.
//
// Precedence:
// 1. Explicit deviceID arg (Config.DeviceID) used verbatim.
// 2. Persistent file at path (Config.DeviceIDPath) read if it exists,
// 1. Explicit deviceID arg (Config.DeviceID) - used verbatim.
// 2. Persistent file at path (Config.DeviceIDPath) - read if it exists,
// otherwise generated and written for future runs.
// 3. Random UUID per run when both inputs are empty.
func resolveDeviceID(deviceID, path string) (string, error) {
@@ -392,12 +392,12 @@ func (c *Client) retryHandshake(ctx context.Context, cfg Config, cancel context.
}
// Don't fail the whole process on liveness reconnect: the carrier
// rebuild may take dozens of seconds (e.g. ICE restart on a flaky
// network). Keep the SOCKS5 listener open and wait handleSocks5
// network). Keep the SOCKS5 listener open and wait - handleSocks5
// will return host-unreachable to clients until we recover. For
// carrier-driven reconnects the callback fires after the link is
// already up, so a missed handshake is more suspicious; cap it.
if reason == "carrier" && attempt >= 5 {
logger.Warnf("client reconnect: exhausted %d handshake attempts (reason=%s) keeping listener up", attempt, reason)
logger.Warnf("client reconnect: exhausted %d handshake attempts (reason=%s) - keeping listener up", attempt, reason)
return
}
select {

View File

@@ -407,7 +407,7 @@ func pumpReader(
}
// isExpectedShutdownErr filters errors that just mean "we asked the conn
// to stop" deadline expirations from our SetDeadline kick, EOF from the
// to stop" - deadline expirations from our SetDeadline kick, EOF from the
// peer half-closing, etc.
func isExpectedShutdownErr(err error) bool {
if err == nil {

View File

@@ -27,7 +27,7 @@ var (
realStress = flag.Bool( //nolint:gochecknoglobals // package-level state intentional
"olcrtc.stress",
false,
"run real provider stress matrix (bulk transfer + sustained echo) requires -olcrtc.real-e2e",
"run real provider stress matrix (bulk transfer + sustained echo) - requires -olcrtc.real-e2e",
)
realStressBulkDuration = flag.Duration( //nolint:gochecknoglobals // package-level state intentional
"olcrtc.stress-bulk-duration",
@@ -183,7 +183,7 @@ func runRealE2EStressCase(t *testing.T, carrierName, transportName, roomURL, ech
}
goroutinesAfter := runtime.NumGoroutine()
// Allow some slack pion/quic spawn helpers that take time to wind down
// Allow some slack - pion/quic spawn helpers that take time to wind down
// after Close, but a real leak shows up as tens of extra goroutines.
const goroutineLeakSlack = 30
if goroutinesAfter > goroutinesBefore+goroutineLeakSlack {
@@ -204,7 +204,7 @@ func runRealE2EStressCase(t *testing.T, carrierName, transportName, roomURL, ech
// MiB/s; videochannel/seichannel ~25 KB/s through 256-byte qr-encoded
// frames at 25 FPS). An asynchronous writer outruns a slow transport,
// fills muxconn / SOCKS / RTP-track buffers, and the deadlocked pipe
// eventually trips a TCP-write deadline which is not a real bug, just
// eventually trips a TCP-write deadline - which is not a real bug, just
// the natural consequence of pumping into a slow pipe with no flow
// control. Request-response naturally rate-limits to the transport's
// actual round-trip throughput, which is what we want to measure.

View File

@@ -110,7 +110,7 @@ const (
// known to flap: it sometimes succeeds and sometimes fails for
// reasons outside our control (third-party server load, lossy SFU
// paths, etc.). The matrix runner records the outcome but does
// not fail the test either way. Use this sparingly prefer
// not fail the test either way. Use this sparingly - prefer
// ExpectPass / ExpectFail when the behaviour is deterministic.
realE2EExpectUnstable
)
@@ -234,7 +234,7 @@ type memoryStream struct {
// video tracks through a real (in-process) WebRTC stack.
//
// streamCtx is owned by the stream itself (cancelled in Close), not
// by the short-lived ctx that Connect receives the video
// by the short-lived ctx that Connect receives - the video
// transport's connectCtx fires its deferred cancel as soon as
// streamTransport.Connect returns, which would otherwise tear down
// the async SDP negotiation goroutine before it can find its peer.
@@ -385,7 +385,7 @@ func (s *memoryStream) SetVideoTrackHandler(cb func(*webrtc.TrackRemote, *webrtc
// transceiver that AddTrack on the peer side will create even if
// SetVideoTrackHandler arrives before AddVideoTrack.
if _, err := s.ensurePC(); err != nil {
// e2e helper: swallow the failure surfaces on the next
// e2e helper: swallow - the failure surfaces on the next
// AddVideoTrack/Connect path that actually needs the PC.
_ = err
}
@@ -813,13 +813,13 @@ func realRoomURL(ctx context.Context, t *testing.T, carrierName string) string {
t.Skip("skip wbstream real e2e: set -olcrtc.real-wbstream-room to an existing room ID")
return ""
case "jitsi":
// Jitsi has no notion of "creating" a room names are conjured
// Jitsi has no notion of "creating" a room - names are conjured
// on first join. The default flag points at meet.cryptopro.ru
// by default. When the flag is left at its default value, a
// per-process random suffix is appended
// to the slug: two participants share a single room by design (one
// pair, one shared key), so any third participant including another
// concurrent test process with the same shared key would corrupt
// pair, one shared key), so any third participant - including another
// concurrent test process with the same shared key - would corrupt
// the wire protocol on both sides. Users overriding the flag are
// trusted to manage room uniqueness themselves.
_ = ctx

View File

@@ -30,7 +30,7 @@ type Capabilities struct {
VideoTrack bool
}
// Credentials are produced by an auth provider duplicated here to avoid an
// Credentials are produced by an auth provider - duplicated here to avoid an
// import cycle between engine and auth.
type Credentials struct {
URL string

View File

@@ -1,8 +1,8 @@
// Package goolom implements an engine.Session backed by the Goolom SFU
// signaling protocol. Goolom is the proprietary SFU developed for Yandex
// Telemost; the on-wire protocol capabilities offer, separated subscriber
// Telemost; the on-wire protocol - capabilities offer, separated subscriber
// and publisher PeerConnections, ack/pong keepalive, slots-based subscribe
// model is what this engine speaks.
// model - is what this engine speaks.
//
// HTTP auth (room-info lookup, telemetry referer, etc.) lives in the auth
// package; this engine consumes a media-server WebSocket URL plus the
@@ -88,7 +88,7 @@ type Session struct {
peerID string
roomID string
credentials string
roomURL string // referer for telemetry opaque to the engine
roomURL string // referer for telemetry - opaque to the engine
telemetryReferer string
refresh func(ctx context.Context) (engine.Credentials, error)

View File

@@ -81,7 +81,7 @@ func TestReconnectWindowEnforcesCapWithinWindow(t *testing.T) {
// TestResetPeerClearsBindingForNewPeer covers fix 032151b: after an
// upper-layer handshake failure the supervisor calls ResetPeer, and the
// next peer in the room must be allowed to latch not blocked by the
// next peer in the room must be allowed to latch - not blocked by the
// previously-latched (now stale) endpoint.
//
// jitsi_test.go has no coverage for this path.
@@ -102,7 +102,7 @@ func TestResetPeerClearsBindingForNewPeer(t *testing.T) {
frameA := makeBridgeFrameForEpoch(t, 0x1111, 0, []byte("from-A"))
js.deliverBridgeMessage(makeBridgeMessageFrom("peerA", map[string]any{rawFieldKey: frameA}), true)
// Peer B tries while A still owns the latch must be dropped.
// Peer B tries while A still owns the latch - must be dropped.
frameB1 := makeBridgeFrameForEpoch(t, 0x2222, 0, []byte("from-B-blocked"))
js.deliverBridgeMessage(makeBridgeMessageFrom("peerB", map[string]any{rawFieldKey: frameB1}), true)
@@ -196,7 +196,7 @@ func TestChurnPeerEpochChanges(t *testing.T) {
t.Fatalf("stale frames delivered: %d (filter regression)", staleDelivered.Load())
}
if delivered.Load() == 0 {
t.Fatal("no frames delivered at all filter is too aggressive")
t.Fatal("no frames delivered at all - filter is too aggressive")
}
}

View File

@@ -138,7 +138,7 @@ type bridgeOutbound struct {
// New creates a new Jitsi engine session.
//
// cfg.URL carries the Jitsi host (e.g. "meet.cryptopro.ru") populated by the
// cfg.URL carries the Jitsi host (e.g. "meet.cryptopro.ru") - populated by the
// jitsi auth provider after parsing the user-supplied room URL. cfg.Extra
// must contain the room name under the "room" key.
func New(_ context.Context, cfg engine.Config) (engine.Session, error) {
@@ -364,7 +364,7 @@ func (s *Session) videoTrackHandler() func(*webrtc.TrackRemote, *webrtc.RTPRecei
// negotiatePC builds the pion PeerConnection, applies Jicofo's offer,
// answers it and registers all the per-side wiring (DTLS state, ICE
// callbacks, transceiver direction). It's branchy on purpose Jingle
// callbacks, transceiver direction). It's branchy on purpose - Jingle
// negotiation has many discrete steps that can fail and each step
// belongs to the same logical operation, so splitting it into helpers
// would obscure the wire order rather than clarify it.
@@ -376,7 +376,7 @@ func (s *Session) negotiatePC(ctx context.Context, jSess *j.Session) error {
// pion auto-registers a default interceptor chain (sender reports,
// receiver reports, NACK, etc.) when none is supplied. Several of
// those probe the DTLS transport on a tick until DTLS comes up
// those probe the DTLS transport on a tick - until DTLS comes up
// (which can take seconds against Jitsi's STUN-only path, or never
// in pathological cases) they spam logs with
// "the DTLS transport has not started yet". JVB performs its own
@@ -423,7 +423,7 @@ func (s *Session) negotiatePC(ctx context.Context, jSess *j.Session) error {
// When sending video, AddTrack already creates the video m-line (sendonly).
// When only receiving, an explicit recvonly transceiver is required so the
// SDP answer includes a video m-line without it JVB does not set up a
// SDP answer includes a video m-line - without it JVB does not set up a
// video forwarding path and ICE stalls. Mirrors the j library reference CLI:
// AddTrack and AddTransceiverFromKind(video,recvonly) are mutually exclusive
// in Plan B; using both produces a malformed SDP.
@@ -469,13 +469,13 @@ func (s *Session) negotiatePC(ctx context.Context, jSess *j.Session) error {
// (trickle ICE) and source-add (other participants' SSRCs) the moment
// it sees us reply to session-initiate. If we started the drain loop
// only after Accept and SendSourceAdd, those stanzas would queue in
// the 64-slot channel while RTP which travels straight over UDP/TURN
// and reaches us in tens of ms arrives first. Pion then drops the
// the 64-slot channel while RTP - which travels straight over UDP/TURN
// and reaches us in tens of ms - arrives first. Pion then drops the
// peer's RTP as "unhandled SSRC, media section has an explicit SSRC"
// because HandleSourceAdd hasn't grafted the SSRC onto the remote SDP
// yet. The peer never produces an OnTrack callback, our handshake
// never gets an ACK, and the tunnel dies. Starting the consumer first
// closes that race window any source-add Jicofo emits is picked up
// closes that race window - any source-add Jicofo emits is picked up
// the instant it lands on the wire.
s.wg.Add(1)
go s.trickleDrainLoop(pc, neg, jSess.LowLevel().Stanzas())
@@ -939,7 +939,7 @@ func (s *Session) peerLatchAccepts(from string) bool {
}
// decodeRaw extracts the bytes from an EndpointMessage produced by the j
// library's BridgeSendRaw helper. Mirrors the unexported colibri.DecodeRaw
// library's BridgeSendRaw helper. Mirrors the unexported colibri.DecodeRaw -
// the j library's BridgeMessage type alias keeps the necessary fields public,
// but the helper itself lives in an internal package.
func decodeRaw(m j.BridgeMessage) []byte {
@@ -963,14 +963,14 @@ func decodeRaw(m j.BridgeMessage) []byte {
//
// 1. Mark the session closed so send/recv loops drop new work.
// 2. Close the pion PeerConnection (stops media, sends DTLS bye). This
// mirrors jvbJingleSession.close() in lib-jitsi-meet note that
// mirrors jvbJingleSession.close() in lib-jitsi-meet - note that
// graceful leave there does NOT send Jingle session-terminate; Jicofo
// learns of the departure from the MUC presence-unavailable stanza
// and only then frees the JVB bridge slot.
// 3. Close the underlying j.Session, which closes the colibri-ws bridge,
// performs the MUC presence-unavailable handshake (LeaveMUCWait
// waits for Prosody to echo our own unavailable presence the
// XMPP-level equivalent of XMPPEvents.MUC_LEFT with a 5s cap),
// waits for Prosody to echo our own unavailable presence - the
// XMPP-level equivalent of XMPPEvents.MUC_LEFT - with a 5s cap),
// and only then tears down the websocket.
// 4. Cancel the supervisor context and wait for goroutines.
//
@@ -979,7 +979,7 @@ func decodeRaw(m j.BridgeMessage) []byte {
// stops replying to our session-terminate IQ. TerminateWait then ate its
// 3s budget and we still left ghost participants behind. lib-jitsi-meet
// avoids this entirely by relying on MUC presence as the single source of
// truth for departure Prosody's MUC layer is far more reliable than
// truth for departure - Prosody's MUC layer is far more reliable than
// Jicofo's IQ handler under load.
func (s *Session) Close() error {
if !s.closed.CompareAndSwap(false, true) {
@@ -1200,7 +1200,7 @@ func (s *Session) CanSend() bool {
return false
}
if s.onData == nil && s.onPeerData == nil {
// pure video mode readiness driven by PC connection state
// pure video mode - readiness driven by PC connection state
s.pcMu.Lock()
ready := s.pc != nil && s.pc.ConnectionState() == webrtc.PeerConnectionStateConnected
s.pcMu.Unlock()
@@ -1234,7 +1234,7 @@ func (s *Session) GetBufferedAmount() uint64 {
//
// Tracks added before Connect are sent as part of the session-accept SDP
// (so Jicofo announces them to other participants automatically). Tracks
// added afterwards are attached to the live PeerConnection Jitsi's
// added afterwards are attached to the live PeerConnection - Jitsi's
// source-add flow is not yet implemented in this engine, so late tracks
// will only be visible on the next reconnect.
func (s *Session) AddVideoTrack(track webrtc.TrackLocal) error {

View File

@@ -52,7 +52,7 @@ const (
// frameBufPool recycles plaintext buffers between Push (decrypts a wire
// frame into a buffer) and Read (consumes the buffer fully then returns
// it). It is global so all Conn instances share the same hot cache
// it). It is global so all Conn instances share the same hot cache -
// most clients in the same process talk to a handful of peers, and
// per-Conn pools fragment the warm set unnecessarily.
var frameBufPool = sync.Pool{ //nolint:gochecknoglobals // intentional process-wide buffer pool

View File

@@ -328,7 +328,7 @@ func (s *Server) reinstallSession(dead *smux.Session) {
s.sessMu.Lock()
if s.session != dead {
// Someone else already reinstalled discard our build.
// Someone else already reinstalled - discard our build.
s.sessMu.Unlock()
_ = newSess.Close()
_ = newConn.Close()
@@ -487,7 +487,7 @@ func (s *Server) getPeerSession(peerID string) *peerSession {
}
// serve drives the smux Accept loop. The first accepted stream on a given
// smux session is the control stream the handshake runs there. Subsequent
// smux session is the control stream - the handshake runs there. Subsequent
// streams are tunnel streams and proxy traffic.
func (s *Server) serve(ctx context.Context) {
if s.peerLn != nil {

View File

@@ -362,7 +362,7 @@ func TestHandleStreamDispatchAfterConnect(t *testing.T) {
req, err := json.Marshal(ConnectRequest{
Cmd: testConnectCmd,
Addr: testConnectAddr,
Port: 1, // unreachable port dispatch will fail dial and exit
Port: 1, // unreachable port - dispatch will fail dial and exit
})
if err != nil {
t.Fatalf("Marshal() error = %v", err)

View File

@@ -1,5 +1,5 @@
// Package common provides building blocks shared by the video-track based
// transports (videochannel, seichannel) fragment/reassembly, ack waiters,
// transports (videochannel, seichannel) - fragment/reassembly, ack waiters,
// and per-peer random IDs. vp8channel does its own KCP-based framing and
// only consumes RandomID.
package common
@@ -208,7 +208,7 @@ func (a *AckRegistry) Unregister(seq uint32) {
}
// Resolve delivers crc to the waiter for seq, if present. A missing waiter
// is silently ignored the sender has already moved on.
// is silently ignored - the sender has already moved on.
func (a *AckRegistry) Resolve(seq, crc uint32) {
a.mu.Lock()
waiter := a.waiters[seq]

View File

@@ -101,7 +101,7 @@ func TestReassemblerStressShuffledFragments(t *testing.T) {
}
}
if dupCount == 0 {
t.Fatal("test injected duplicates but reassembler reported none duplicate path not exercised")
t.Fatal("test injected duplicates but reassembler reported none - duplicate path not exercised")
}
t.Logf("delivered %d/%d messages, observed %d duplicates", len(delivered), messages, dupCount)
}

View File

@@ -135,7 +135,7 @@ func New(ctx context.Context, cfg transport.Config) (transport.Transport, error)
}
stream := &engineVideoSession{session: session, vt: vt}
// Stream/track IDs must be unique per peer Jitsi rejects session-accept
// Stream/track IDs must be unique per peer - Jitsi rejects session-accept
// when msid collides with another participant in the conference.
track, err := webrtc.NewTrackLocalStaticSample(
webrtc.RTPCodecCapability{
@@ -542,4 +542,3 @@ func decodeTransportFrame(data []byte) (transportFrame, error) {
return transportFrame{}, ErrUnexpectedFrameType
}
}

View File

@@ -1,6 +1,6 @@
// Package transport defines transport abstractions and registry.
//
// A transport encodes byte payloads onto a carrier (engine) primitive either
// A transport encodes byte payloads onto a carrier (engine) primitive - either
// a reliable byte stream (datachannel) or a video track (videochannel,
// seichannel, vp8channel). Transport-specific tuning lives in per-transport
// Options types; the common configuration shared by every transport lives in
@@ -41,7 +41,7 @@ type Transport interface {
Features() Features
// Reconnect asks the underlying carrier (engine) to tear down and
// re-establish the SFU connection. Upper layers call this when a
// liveness probe declares the link dead useful when the engine has
// liveness probe declares the link dead - useful when the engine has
// not yet noticed silent packet loss.
Reconnect(reason string)
}

View File

@@ -650,7 +650,7 @@ func (p *streamTransport) handleInboundFrame(frame transportFrame) {
p.sendAck(frame.seq, frame.crc, frame.fragIdx)
case common.ResultPartial, common.ResultDuplicate:
// Every fragment we successfully decoded gets acked, including
// duplicates under retransmits the sender may have lost the
// duplicates - under retransmits the sender may have lost the
// earlier ack and is waiting on this one.
p.sendAck(frame.seq, frame.crc, frame.fragIdx)
case common.ResultIgnore:

View File

@@ -122,7 +122,7 @@ func runChaosLoopback(t *testing.T, msgs [][]byte, cfg chaosCfg, timeout time.Du
var droppedAB, droppedBA atomic.Uint64
go chaosPump(t, stop, a2b, rtB, cfg, &droppedAB)
// Return path stays clean by default KCP ACKs must come back reliably
// Return path stays clean by default - KCP ACKs must come back reliably
// for fair loss measurement; loss on one direction is enough to stress.
go chaosPump(t, stop, b2a, rtA, chaosCfg{}, &droppedBA)
@@ -161,7 +161,7 @@ func TestKCPSurvivesModeratePacketLoss(t *testing.T) {
dur, dropped := runChaosLoopback(t, msgs, chaosCfg{lossRatio: 0.10, seed: 0xC0FFEE}, 20*time.Second)
t.Logf("delivered %d msgs in %s with %d packets dropped (10%% loss)", len(msgs), dur, dropped)
if dropped == 0 {
t.Fatal("chaos pump did not drop any packets loss injection broken")
t.Fatal("chaos pump did not drop any packets - loss injection broken")
}
}
@@ -259,7 +259,7 @@ func TestKCPRecoversFromBurstLoss(t *testing.T) {
}
// TestKCPThroughputBaseline establishes a perfect-channel throughput floor.
// Not an assertion if this number regresses meaningfully on the same
// Not an assertion - if this number regresses meaningfully on the same
// hardware, something changed in KCP options (window size, MTU, tick).
func TestKCPThroughputBaseline(t *testing.T) {
if testing.Short() {

View File

@@ -143,7 +143,7 @@ func New(ctx context.Context, cfg transport.Config) (transport.Transport, error)
}
stream := &engineVideoSession{session: session, vt: vt}
// Stream/track IDs must be unique per peer Jitsi rejects session-accept
// Stream/track IDs must be unique per peer - Jitsi rejects session-accept
// when msid collides with another participant in the conference.
track, err := webrtc.NewTrackLocalStaticSample(
webrtc.RTPCodecCapability{

View File

@@ -10,7 +10,7 @@ import (
// conn wraps a Session as a net.Conn.
// Read is backed by an io.Pipe fed by the engine's OnData callback.
// Write calls Session.Send.
// Deadlines are not supported callers should use context cancellation.
// Deadlines are not supported - callers should use context cancellation.
type conn struct {
s *Session
}

View File

@@ -1,6 +1,6 @@
// Package olcrtc exposes olcrtc as an embeddable Go library.
//
// Typical usage obtain a [net.Conn]-compatible handle and dial:
// Typical usage - obtain a [net.Conn]-compatible handle and dial:
//
// sess, err := olcrtc.New(ctx, olcrtc.Config{
// Engine: "livekit",
@@ -9,7 +9,7 @@
// })
// if err != nil { ... }
// conn, err := sess.Dial(ctx) // blocks until WebRTC data channel is ready
// // conn implements net.Conn pass it to sing-box / any io.ReadWriter consumer
// // conn implements net.Conn - pass it to sing-box / any io.ReadWriter consumer
//
// Built-in auth providers (jitsi, telemost, wbstream):
//