syntax = "proto3"; package gospeak.livedemo.v1; option go_package = "gospeak-live-sfu-demo/gen"; // LiveSFU 是直播 SFU 分流 Demo 的控制面契约(protobuf / gRPC)。 // // 媒体面(WebRTC SDP 交换)不在此契约内:浏览器与 Cloudflare Realtime / SRS // 直连,经本服务反向代理转发(服务端注入 AppSecret / stream token)。 // 本契约只负责房间、后端、发布/订阅拓扑的协调与扇出状态广播。 service LiveSFU { rpc GetConfig(GetConfigRequest) returns (GetConfigResponse); rpc ListRooms(ListRoomsRequest) returns (ListRoomsResponse); rpc Publish(PublishRequest) returns (PublishResponse); rpc Subscribe(SubscribeRequest) returns (SubscribeResponse); rpc StopStream(StopStreamRequest) returns (StopStreamResponse); rpc WatchRoom(WatchRoomRequest) returns (stream RoomEvent); } enum BackendKind { BACKEND_KIND_UNSPECIFIED = 0; BACKEND_KIND_CLOUDFLARE = 1; // Cloudflare Realtime(主 SFU) BACKEND_KIND_SRS = 2; // SRS(次级 / 本地对照) } message IceServer { repeated string urls = 1; string username = 2; string credential = 3; } message GetConfigRequest {} message BackendInfo { BackendKind kind = 1; string name = 2; bool configured = 3; bool primary = 4; } message GetConfigResponse { repeated BackendInfo backends = 1; string candidate = 2; bool token_required = 3; } // StreamTarget 表示一个房间在某后端的一条分发目标(SFU 扇出出口)。 message StreamTarget { BackendKind backend = 1; string session_id = 2; // Cloudflare: 发布者 sessionId string stream = 3; // SRS: stream 名 string publish_token = 4;// SRS: 推流 JWT(可选) string url = 5; // 拉流播放地址(SRS WHEP,可选) int64 published_at = 6; } message Room { string name = 1; repeated StreamTarget targets = 2; } message ListRoomsRequest {} message ListRoomsResponse { repeated Room rooms = 1; } message PublishRequest { string room = 1; BackendKind backend = 2; string identity = 3; } message PublishResponse { string session_id = 1; string stream = 2; string publish_token = 3; repeated IceServer ice_servers = 4; StreamTarget target = 5; } message SubscribeRequest { string room = 1; BackendKind backend = 2; string identity = 3; } message SubscribeResponse { string session_id = 1; string stream = 2; string publisher_session_id = 3; repeated IceServer ice_servers = 4; } message StopStreamRequest { string room = 1; BackendKind backend = 2; } message StopStreamResponse { bool ok = 1; } message WatchRoomRequest { string room = 1; } message RoomEvent { string room = 1; repeated StreamTarget targets = 2; }