Skip to content

WSMServer

WSMServer — мост между WSMedia WebSocket session и внутренним UDP media translator. Он не знает про UI-устройства напрямую. Его единица маршрутизации — ssrc.

Основной алгоритм

flowchart TB
    Frame[WS binary media frame]
    Header[Parse WsBinaryMediaHeader]
    SSRC[ssrc]
    Find[Find socket by ssrc]
    Create[Create UDP socket for ssrc]
    SendUDP[Send payload to 127.0.0.1:port]
    Translator[Media translator]

    Frame --> Header --> SSRC --> Find
    Find -->|exists| SendUDP
    Find -->|missing| Create --> SendUDP
    SendUDP --> Translator

Обратная доставка

sequenceDiagram
    participant Translator
    participant UDP as Per-SSRC UDP socket
    participant WSM as WSMServer
    participant WS as WSMedia session
    participant Client

    Translator->>UDP: RTP/RTCP packet
    UDP->>WSM: callback(data, src address, local socket port)
    WSM->>WSM: local port -> ssrc -> session
    WSM->>WS: write WSM binary media frame
    WS-->>Client: frame with ssrc
    Client->>Client: demux by ssrc

Cleanup session

flowchart TB
    Logout[WSMedia logout / socket closed]
    End[WSMServer::EndSession(session)]
    Iterate[Iterate sockets]
    Match{socket.session == session}
    Stop[Stop UDP socket]
    Erase[Erase ssrc and local port mappings]

    Logout --> End --> Iterate --> Match
    Match -->|yes| Stop --> Erase
    Match -->|no| Iterate

Подтверждённый инвариант

Одна WSMedia session может владеть несколькими ssrc. Это видно из текущей реализации:

  • sockets хранит ssrc -> Socket{ session, udp_socket };
  • ports хранит udp local port -> ssrc;
  • Send(session, data) создаёт UDP socket по ssrc, если его ещё нет;
  • SendToWS(...) находит ssrc по local UDP port и пишет frame в сохранённую session;
  • EndSession(session) удаляет все sockets, чей socket.session совпадает с закрываемой session.

Что нельзя ломать

  • Нельзя делать session -> single ssrc.
  • Нельзя удалять все ssrc клиента при одном device_disconnect, если media session остаётся живой.
  • Нельзя считать количество WSMedia sessions количеством устройств.
  • Нельзя маршрутизировать WSMedia payload по device_id; только по ssrc.