Skip to content

web-client UML

Эта страница описывает runtime-структуру browser-клиента. Это не полная UML-модель всех React-компонентов, а карта основных узлов, которые важны для протокола, media, stale recovery и отладки.

Component diagram

flowchart TB
    subgraph Browser[Browser / PWA]
        UI[Index.tsx / React UI]
        VG[VideograceClient.ts<br/>client facade]
        Store[React state callbacks<br/>contacts, messages, calls, media state]
        Offline[Offline storage<br/>Storage + MessagesStorage]
        Push[Push notifications]
    end

    subgraph Control[Control plane]
        CWS[ControlWS.ts]
        Bus[EventBus]
    end

    subgraph Media[Media plane]
        Pub[WebRTCPublishSession<br/>mic/cam/screen publish]
        AudioSub[WebRTCSubscribeSession<br/>remote audio]
        VideoSub[WebRTCVideoSubscribeSession<br/>remote video/screen]
        Capture[MicSession / CameraSession / ScreenSession]
        WSM[MediaMuxSocket + MediaChannel<br/>initial/forced fallback]
    end

    subgraph Server[VideoGrace Server]
        Command[CommandLoop]
        RTC[RTC node / WebRTC Gateway]
        WSMServer[WSMServer]
        Translator[Translator]
        StorageAPI[HTTPS storage API]
    end

    UI --> VG
    VG --> Store
    VG --> Offline
    VG --> Push
    VG --> CWS
    CWS --> Bus
    Bus --> VG

    VG --> Capture
    VG --> Pub
    VG --> AudioSub
    VG --> VideoSub
    VG -. fallback .-> WSM

    CWS <-->|JSON commands| Command
    Pub <-->|ICE/DTLS/SRTP| RTC
    AudioSub <-->|ICE/DTLS/SRTP| RTC
    VideoSub <-->|ICE/DTLS/SRTP| RTC
    WSM <-->|WSM binary frames| WSMServer
    RTC <-->|RTP/RTCP bridge| Translator
    WSMServer <-->|UDP RTP/RTCP by SSRC| Translator
    Offline <-->|REST blobs| StorageAPI

Package/class view

classDiagram
    class Index {
        <<React page>>
        +uiState
        +callsVideograceClient()
    }

    class VideograceClient {
        +connect()
        +joinConference()
        +toggleMic()
        +toggleCam()
        +toggleScreen()
        +sendMessage()
        +handleDeviceConnect()
        +recoverForegroundMedia()
        -remoteMediaSessions
        -localMediaSessions
    }

    class ControlWS {
        +connect()
        +sendCommand()
        +sendConnectToConference()
        +sendCreatedDevice()
        +sendWebRTCOffer()
        +sendWebRTCIceCandidate()
        +checkStaleOrReconnect()
        -controlInstanceId
        -authToken
    }

    class EventBus {
        +on()
        +off()
        +emit()
    }

    class Storage {
        +openDb()
        +saveGroups()
        +saveContacts()
        +saveConferences()
    }

    class MessagesStorage {
        +init()
        +upsertMessage()
        +loadAllMessagesFromDb()
        +getMessagesByChat()
    }

    class WebRTCPublishSession {
        +start()
        +stop()
        +getHealth()
        +onConnectionStateChange()
    }

    class WebRTCSubscribeSession {
        +start()
        +stop()
        +getHealth()
        +attachAudioElement()
    }

    class WebRTCVideoSubscribeSession {
        +start()
        +stop()
        +getHealth()
        +attachVideoElement()
    }

    class MediaMuxSocket {
        +connect()
        +registerHandler()
        +sendRtp()
        +sendRtcp()
    }

    class MediaChannel {
        +start()
        +stop()
        +sendRtpInit()
        +requestKeyFrame()
    }

    Index --> VideograceClient
    VideograceClient --> ControlWS
    ControlWS --> EventBus
    VideograceClient --> Storage
    VideograceClient --> MessagesStorage
    VideograceClient --> WebRTCPublishSession
    VideograceClient --> WebRTCSubscribeSession
    VideograceClient --> WebRTCVideoSubscribeSession
    VideograceClient ..> MediaChannel : initial/forced WSM fallback
    MediaChannel --> MediaMuxSocket

Main responsibilities

Module Responsibility Must not own
Index.tsx React UI, routing between login/chats/conference, user interactions. Protocol state machine, WebRTC negotiation details.
VideograceClient.ts Facade over protocol, contacts/messages/conferences, device lifecycle, media orchestration. Low-level WebSocket framing, RTP packetization internals.
ControlWS.ts CommandLoop WebSocket, auth, reconnect, control_instance_id, JSON command send/dispatch, WebRTC signaling. UI state, media capture/render.
Storage / MessagesStorage IndexedDB offline cache for contacts/groups/conferences/messages. Server authority, conflict resolution outside loaded state.
WebRTCPublishSession Local mic/cam/screen RTCPeerConnection publish endpoint. Creating server-side devices.
WebRTCSubscribeSession Remote audio subscribe endpoint and browser audio playback attach. Creating remote devices or WSM fallback policy.
WebRTCVideoSubscribeSession Remote video/screen subscribe endpoint, video element attach, RTP progress health. Conference layout ownership.
MediaMuxSocket / MediaChannel WSM fallback transport and legacy audio/video render pipeline. Automatic fallback after already-established RTC.

Control and media sequence

sequenceDiagram
    participant UI as Index.tsx
    participant VG as VideograceClient
    participant CWS as ControlWS
    participant Server as CommandLoop
    participant Pub as WebRTCPublishSession
    participant Sub as WebRTC subscribe session
    participant RTC as RTC node / Gateway

    UI->>VG: connect(login/password)
    VG->>CWS: connect(control_instance_id)
    CWS->>Server: connect_request
    Server-->>CWS: connect_response(access_token, routes/state)
    CWS-->>VG: connected + lists
    VG-->>UI: contacts/conferences/messages state

    UI->>VG: joinConference(tag, mic/cam flags)
    VG->>CWS: connect_to_conference_request
    Server-->>CWS: connect_to_conference_response
    Server-->>CWS: device_connect(remote devices)
    CWS-->>VG: device_connect events
    VG->>Sub: start remote WebRTC subscribe
    Sub->>CWS: webrtc_offer(scope=audio/video-subscribe)
    CWS->>Server: webrtc_offer
    Server-->>CWS: webrtc_answer
    Sub-->>RTC: ICE/DTLS/SRTP receive

    UI->>VG: toggleMic(true) / toggleCam(true)
    VG->>CWS: device_params
    Server-->>CWS: device_connect(my=1)
    CWS-->>VG: local device binding
    VG->>Pub: start WebRTC publish
    Pub->>CWS: webrtc_offer(scope=audio/video)
    CWS->>Server: webrtc_offer
    Server-->>CWS: webrtc_answer
    Pub-->>RTC: ICE/DTLS/SRTP publish

Stale recovery sequence

sequenceDiagram
    participant Browser
    participant CWS as ControlWS
    participant VG as VideograceClient
    participant Server as CommandLoop
    participant In as Remote WebRTC sessions
    participant Out as Local publish sessions

    Browser--xCWS: network loss / 1006 / background stale
    CWS->>CWS: scheduleReconnect()
    CWS->>Server: connect_request(same control_instance_id)
    Server-->>CWS: connect_response(restore_stale_session=true, stale_conference_tag)
    CWS-->>VG: reconnected(data)

    VG->>VG: keep activeConferenceTag/isInConference
    VG->>VG: do not send full join
    VG->>VG: do not repeat device_params for active local devices
    VG->>In: retry stalled/error remote sessions
    In->>CWS: new webrtc_offer with same remote binding
    VG->>Out: recover active local publish sessions
    Out->>CWS: new webrtc_offer with same sourceDevice

Key invariant: stale restore is a control-session replacement, not a new conference join. If a WebRTC endpoint was already connected/ok, recovery must restart WebRTC with the same device binding and must not degrade to WSM.

Media state model

stateDiagram-v2
    [*] --> NoDevice
    NoDevice --> DevicePending: device_params sent
    DevicePending --> DeviceCreated: device_connect my=1
    DeviceCreated --> RTCConnecting: WebRTC offer sent
    RTCConnecting --> RTCOK: answer + ICE connected
    RTCConnecting --> InitialFallback: initial failure in auto mode
    InitialFallback --> WSMOK: WSM fallback connected
    RTCOK --> RTCStalled: no RTP / disconnected / failed
    RTCStalled --> RTCRestarting: restart/backoff
    RTCRestarting --> RTCOK: new endpoint connected
    RTCRestarting --> RTCError: restart budget exhausted
    RTCOK --> Stopping: toggle off / leave
    WSMOK --> Stopping: toggle off / leave
    RTCError --> Stopping
    Stopping --> NoDevice

InitialFallback разрешен только если WebRTC не поднялся изначально в auto mode. Переход RTCStalled --> WSMOK запрещен для endpoint'ов, которые уже были успешно подняты через WebRTC.

Debug checklist

  • Если UI показывает “RTC красный”, сначала определить endpoint: local publish или remote subscribe.
  • Для local publish проверить device_connect my=1, sourceDevice, webrtc_offer, webrtc_answer, ICE state и local recovery timer.
  • Для remote subscribe проверить remote device_connect, receiver_ssrc, endpoint_id, inbound RTP progress и restart backoff.
  • При stale проверить connect_response.restore_stale_session=true и отсутствие повторного connect_to_conference_request/device_params.
  • Если после stale появился MediaChannel/WSM для уже active RTC endpoint, это нарушение recovery policy.