Skip to content

Как писать клиентов

Новый клиент VideoGrace должен разделять control lifecycle и media lifecycle. Это главный способ избежать гонок и дублирования устройств.

flowchart TB
    Start[Start process]
    Login[CommandLoop login]
    Token[Receive access_token]
    Join[connect_to_conference_request]
    Media[Open media path: UDP primary or WSMedia fallback]
    Publish[Optional: create local devices]
    Render[Optional: subscribe remote devices]
    Events[Process events until shutdown]
    Cleanup[device_disconnect + disconnect_from_conference + close transports]

    Start --> Login --> Token --> Join --> Media
    Media --> Publish
    Media --> Render
    Publish --> Events
    Render --> Events
    Events --> Cleanup

Минимальный state machine

stateDiagram-v2
    [*] --> Disconnected
    Disconnected --> Connecting: open CommandLoop
    Connecting --> Ready: connect_response OK
    Ready --> Conferencing: connect_to_conference_response OK
    Conferencing --> Publishing: device_connect my=1
    Conferencing --> Receiving: device_connect my=0
    Publishing --> Conferencing: device_disconnect local
    Receiving --> Conferencing: device_disconnect remote
    Conferencing --> Ready: disconnect_from_conference
    Ready --> Disconnected: disconnect/logout

Типы клиентов

Тип Что делает Примеры
UI client Управляет пользователем, публикует и принимает media, сообщения, звонки. web-client, native Client.
Publisher bot Подключается к конференции и публикует synthetic/file media. Services/FilePlayer.
Receiver bot Подключается к конференции и принимает/обрабатывает remote media. Services/Recorder.
AI agent Принимает audio/text/context, отправляет ответы или команды. Планируемый Python client.

Control client contract

Клиент обязан:

  • открыть CommandLoop;
  • отправить connect_request;
  • сохранить id, connection_id, access_token, secure_key, max_output_bitrate;
  • подключиться к конференции через connect_to_conference_request;
  • обрабатывать change_member_state, device_connect, device_disconnect, resolution_change, microphone_active;
  • корректно закрывать локальные устройства перед выходом.

Publisher contract

Publisher создает локальные capturer devices:

sequenceDiagram
    participant Bot
    participant Control
    participant Server
    participant Media

    Bot->>Control: device_params(type, name, resolution)
    Server-->>Bot: device_connect(my=1, device_id, author_ssrc, port, secure_key)
    Bot->>Media: attach author_ssrc
    Bot->>Media: send RTP packets to port
    Server-->>Others: device_connect(my=0, receiver_ssrc, port)

Publisher не должен сам придумывать device_id. Его выдает сервер.

Receiver contract

Receiver создает renderer session на каждый remote device_connect:

sequenceDiagram
    participant Server
    participant Bot
    participant Media
    participant Decoder

    Server-->>Bot: device_connect(my=0, receiver_ssrc, author_ssrc, port, codec, secure_key)
    Bot->>Media: attach receiver_ssrc
    Bot->>Media: send RTP init / RTCP ForceKeyFrame for video
    Media-->>Bot: RTP frames by receiver_ssrc
    Bot->>Decoder: decrypt/collect/decode/record/process

Receiver должен удалять renderer по device_disconnect.

Media transport выбор

Runtime Основной путь Fallback
Native C++ UDP RTP/RTCP WSMedia WSS mux
Browser WebRTC ICE/DTLS/SRTP WSMedia WSS mux
Mobile Android/iOS WebRTC ICE/DTLS/SRTP По решению мобильного SDK
Python/AI На первом этапе WSMedia WSS mux UDP можно добавить позже при необходимости

Практический чеклист нового клиента

  1. Реализовать CommandLoop WS.
  2. Реализовать parser/serializer нужных JSON-команд.
  3. Реализовать conference/device state machine.
  4. Реализовать media transport: UDP или WSMedia.
  5. Реализовать RTP/RTCP packetization или decoding.
  6. Реализовать cleanup: локальные devices, renderer sessions, conference, sockets.
  7. Добавить reconnect policy отдельно для control/media/blob.
  8. Зафиксировать ограничения клиента в этой документации.