Files
xsynergy-android/docs/livekit-messages.md
chaoq 202ebef35d add docs folder.
Signed-off-by: chaoq <chaoq@gxtech.ltd>
2025-09-17 15:55:45 +08:00

8.1 KiB
Raw Blame History

消息定义


概述

消息通道保持与业务的隔离性,包括鉴权等,独立于业务存在。 做为消息通道理论上不应该与客户端用户登陆状态相关应该只与应用关即理论上一个应用应该在打开后即建立连接。用户登陆后应该在应用服务器中将此连接与用户进行关联而已将要发送给此用户的消息发送到此通道中即可。当然MQTT服务在建立连接断开连接等事件结点均会发出WebHook消息。WebHook对应的被通知业务服务应该是HTTP服务。 MQTT消息结构体默认应该为MessagePack格式 It's like JSON. but fast and small.

MQTT WebHooks

配置WebHook链接地址

  • 此服务地址不应该与客户端API一样对客户端开放如要开放也请做好安全限制
  • 此服务请求结构体支持MessagePack/Json格式可配置默认MessagePack并在URL中配有签名字段可选约定密钥配置在MQTT服务器中

MQTT业务消息

消息结构体主要属性有两个event, data以激光笔为例

{
    "event":"laser-pointer",
    "data":{
        "start":[0.5,0.3],
        "end":[0.5,0.3],
        "color":[255,0,0],
        "thickness":3
    }
}

消息接收者范围由MQTT的TOPIC来约束。

本文中默认topic根约定为: /zrsk/remote-assistant,下文中的所有TOPIC默认需要在头部添加{{TOPIC-ROOT}}来表达,如:

  • /room/78Ue 业务中完整TOIPC应为 {{TOPIC-ROOT}}/room/78Ue,即:/zrsk/remote-assistant/room/78Ue

如要发送给房间指定用户消息体对应的Topic应该为:

{{TOPIC-ROOT}}/room/{{ROOM_ID}}/user/{{UID}},

如果是房间广播消息那么消息体对应的Topic应该为: {{TOPIC-ROOT}}/room/{{ROOM_ID}},

在进入房间后客户端应该订阅如上两个对应的TOPIC即可实现对此房间此类消息的监听。

客户端消息定义

发起呼叫

用户创建会议并呼叫会议参与方一般每2秒发送一次消息收到一次消息持续UI提示6秒收到取消呼叫的消息显示呼叫被取消后显示呼叫取消的UI停留2秒后隐藏。或在呼叫UI显示6秒后中间没有新的呼叫消息到达同样视为呼叫取消。

  • topic: {{TOPIC-ROOT}}/user/{{UID}} ,UID为被呼叫的用户ID
  • event: call
  • data:
    • room_id: string 会议ID
    • title: string 发起呼叫的会议名称
    • caller: uid 呼叫者ID收到后应该从服务端获取此用户的用户信息如getBriefUserInfo

呼叫取消

取消对指定用户参会的呼叫邀请

  • topic: {{TOPIC-ROOT}}/user/{{UID}} ,UID为被呼叫的用户ID
  • event: call-cancel
  • data:
    • room_id: string 会议ID
    • title: string 发起呼叫的会议名称
    • caller: uid 呼叫者ID收到后应该从服务端获取此用户的用户信息如getBriefUserInfo

激光笔

  • topic: {{TOPIC-ROOT}}/room/{{ROOM_ID}}/user/{{UID}}
  • event: laser-pointer
  • data:
    • start: [2]float, 点击按下时,当前点坐标相对屏幕坐标的百分比,结构为[x,y]如屏幕宽1920当前点x是960则这里应该传递0.5,
    • end: [2]float, 当点击抬起时,当前点坐标相对屏幕坐标的百分比,结构为[x,y]如屏幕宽1920当前点x是960则这里应该传递0.5,
    • color: [3]uint8, 结构顺序为RGB,即红绿三原色范围分别为0-255,如[255,0,0],即代表纯红色。
    • thicknessuint, 连接start,与end之间的线段粗细值单位是像素一般为大于1的整数

冻屏

  • topic: {{TOPIC-ROOT}}/room/{{ROOM_ID}}/user/{{UID}}
  • event: screen-freeze
  • data:
    • uid: string, 发起冻屏的用户ID收到此消息后默认将此用户发布的视频流放到最大此用户开始将之前用户的视频分享界面截图做为画板在上面进行绘画过程视频流共享给当前会议内的所有人。

广播消息

  • topic:
    • 全局: {{TOPIC-ROOT}}/system , 客户端启动后建立MQTT连接后应该全程订阅
    • 会议中: {{TOPIC-ROOT}}/room/{{ROOM_ID}} ,客户端参与指定会议后,开始订阅,退出会议或会议结束后应该取消订阅
    • 用户消息: {{TOPIC-ROOT}}/user/{{UID}}, 客户端启动后建立MQTT连接后,用户登陆后应该使用当前用户ID来全程订阅发布到此Topic下可能的消息类型有
      • 管理员私信
      • 聊天消息
      • 会议呼叫
      • 会议管理消息(禁麦,被踢出会议等)
      • 文件预览
  • event: boardcast
  • data:
    • title: string 广播消息标题
    • message: string 消息内容本期暂时固定消息样式即可后期考虑支持html富文本格式
    • sender:
      • name: string 发送者名称

发起对指定用户的文件预览

在会议中发起对指定用户的文件预览首先需要将文件上传后得到文件的相对路径客户端收到消息后再将文件路径拼接到文件预览服务API中从而实现预览。

  • topic: {{TOPIC-ROOT}}/room/{{ROOM_ID}}/user/{{UID}}
  • event: file_preview
  • data:
    • name: string 文件名称
    • path: string 文件路径
    • mime_type: string 文件类型,如: image/jpegapplication/pdf

会议字幕

会议中所有用户的发言音频转字幕

  • topic: {{TOPIC-ROOT}}/room/{{ROOM_ID}}
  • event: meeting-asr-subtitle
  • data:
    • uid: string 用户ID
    • seg: string 用户当前ASR转换的结果
    • status: string,可能的值为:正在讲话中:steaming,本句已经说完:final

会议结束

  • topic: {{TOPIC-ROOT}}/room/{{ROOM_ID}}
  • event: end-meeting
  • data:
    • reason: string optional 可由系统生成详细的原因如此字段存在此信息应该以toast的方式在客户端进行提示。如“XX用户挂断了”或“管理员结束了本次会议”
    • code: int, 0: 未知原因1:用户挂断2:管理员解散会议

强制切换指定用户当前发布的视频源

  • topic: {{TOPIC-ROOT}}/room/{{ROOM_ID}}/user/{{UID}}
  • event: change-video-source
  • data:
    • stream_id: string 可选的值由客户端在进入会议后上报本地可用的localStream设备列表

服务端消息定义

房间消息

  • topic: {{TOPIC-ROOT}}/system/room/{{ROOM_ID}}/event/{{EVENT}} // 此Topic不允许用户客户端订阅

    • ROOM_IDstring 同room.name
    • EVENT: string 同消息中的event
  • event: room-event

    • room_started: 会议开始
    • room_finished: 会议结束
    • participant_joined: 有人参会
    • participant_left: 有人退出会议
    • track_published: 有人发布流
    • track_unpublished: 有人停止流发布
  • data:

    • event: string 事件
    • room: Room 结构体参考Room
    • participant: ParticipantInfo 结构体参考ParticipantInfo 当event与participant或track相关时可用
    • track: TrackInfo 结构体参考TrackInfo 当event为track_unpublished或track_unpublished时可用 消息格式参考
{
    "event": "room_started",
    "room": {
        "sid": "RM_g8qHzqsDLYbf",
        "name": "f37p-vltp",
        "empty_timeout": 300,
        "departure_timeout": 20,
        "creation_time": 1735203759,
        "turn_password": "UodxhWh76Wtf3h2V9XmfiyisKKxpik93BFuyqdvTzG4",
        "enabled_codecs": [
            {
                "mime": "audio/opus"
            },
            {
                "mime": "audio/red"
            },
            {
                "mime": "video/VP8"
            },
            {
                "mime": "video/H264"
            },
            {
                "mime": "video/VP9"
            },
            {
                "mime": "video/AV1"
            }
        ]
    },
    "participant": {
        "sid": "PA_5cRs7GQixq7Q",
        "identity": "Kilroy001",
        "state": 2,
        "joined_at": 1735203759,
        "name": "Kilroy001",
        "version": 2,
        "permission": {
            "can_subscribe": true,
            "can_publish": true,
            "can_publish_data": true
        }
    },
    "id": "EV_e5mj23v3QCST",
    "created_at": 1735203759
}