API 参考(v1)

目录

通用约定

Base URL/api/v1

所有 HTTP 响应均包含以下安全头:

Header
X-Request-ID 请求追踪 ID(自动生成或透传客户端值)
X-Content-Type-Options nosniff
X-Frame-Options DENY

错误响应统一格式:

{
  "type": "error",
  "payload": { "code": 2004, "message": "room_not_found" }
}

REST 端点

POST /rooms — 创建房间

请求体(均可选):

{
  "id": "my-room-001",
  "maxParticipants": 8,
  "metadata": { "title": "Stand-up" }
}

201 Created

{
  "id": "my-room-001",
  "maxParticipants": 8
}

若不指定 id,服务端自动生成 UUID。


GET /rooms/{id} — 查询房间

200 OK

{
  "id": "my-room-001",
  "participants": 3
}

404 Not Found

{
  "type": "error",
  "payload": { "code": 2004, "message": "room_not_found" }
}

POST /rooms/{id}/join-token — 签发令牌

请求头(可选):X-Admin-Key: <key>(常量时间比较)

请求体

{
  "userId": "user-alice",
  "displayName": "Alice",
  "role": "speaker",
  "ttlSeconds": 600
}
字段 必填 说明
userId 业务用户标识
displayName 显示名
role viewer / speaker / moderator,默认 speaker
ttlSeconds Token 有效期(秒),默认 900,最大 3600

200 OK

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "expiresIn": 600
}

GET /ice-servers — ICE 配置

200 OK

[
  {
    "urls": ["stun:stun.l.google.com:19302"]
  },
  {
    "urls": ["turn:turn.example.com:3478"],
    "username": "turnuser",
    "credential": "turnpass",
    "ttl": 600
  }
]

GET /healthz — 存活探针

200 OKok


GET /readyz — 就绪探针

检测 Redis 连接可用性(启用时)。

状态码 含义
200 ok
503 redis unavailable / redis unreachable

GET /metrics — Prometheus 指标

返回 Prometheus 文本格式指标,namespace 为 signal_


WebSocket 信令

连接

GET /ws/v1?token=<JWT>

或使用 Header:Authorization: Bearer <JWT>

连接建立后,客户端必须首先发送 join 消息,否则连接将被关闭。


消息信封

所有消息遵循统一信封格式。服务端自动填充 idtsfrom 字段。

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "version": "v1",
  "type": "offer",
  "to": "peer-b",
  "from": "peer-a",
  "ts": 1707800000000,
  "payload": { "sdp": "v=0..." }
}
字段 说明
id UUID,服务端自动生成
version 协议版本,当前固定 v1
type 消息类型
to 目标 peer ID,省略或 * 表示广播
from 发送方 peer ID(服务端填充)
ts Unix 毫秒时间戳(服务端填充)
payload 消息体,结构因 type 而异

客户端 → 服务端

类型 payload 说明
join { roomId, displayName?, role? } 加入房间
offer { to, sdp } SDP Offer
answer { to, sdp } SDP Answer
trickle { to, candidate } ICE 候选
chat { to?, text } 文本消息(to 省略则广播)
mute / unmute { target? } 静音控制(需权限)
leave 离开房间

示例 — join

{
  "version": "v1",
  "type": "join",
  "payload": { "roomId": "room-001", "displayName": "Alice" }
}

示例 — offer

{
  "version": "v1",
  "type": "offer",
  "to": "peer-b",
  "payload": { "sdp": "v=0\r\no=- 46117317..." }
}

服务端 → 客户端

类型 payload 说明
joined { self, peers[], iceServers[] } 加入成功,返回成员列表与 ICE 配置
participant-joined { id, displayName, role } 新成员通知
participant-left { id } 成员离开通知
offer / answer / trickle 同上 转发对端消息
chat { text } 转发文本消息
mute / unmute 转发控制消息 对端或系统静音控制
error { code, message, details? } 错误

示例 — joined

{
  "id": "...",
  "version": "v1",
  "type": "joined",
  "ts": 1707800000000,
  "payload": {
    "self": { "id": "peer-a", "role": "speaker" },
    "peers": [
      { "id": "peer-b", "role": "speaker", "displayName": "Bob" }
    ],
    "iceServers": [
      { "urls": ["stun:stun.l.google.com:19302"] }
    ]
  }
}

示例 — error

{
  "version": "v1",
  "type": "error",
  "payload": { "code": 2003, "message": "forbidden" }
}

错误码

含义 说明
2001 invalid_message 消息格式不合法
2002 unauthorized 未认证或 Token 过期
2003 forbidden 权限不足
2004 room_not_found 房间不存在
2006 unsupported_type 不支持的消息类型
2007 rate_limited 超出速率限制
2010 bad_state / room_full 状态异常或房间已满
3000 internal_error 服务端内部错误

配置环境变量

变量 默认值 说明
SIGNAL_LOG_LEVEL info 日志级别(debug / info / warn / error)
SIGNAL_ADDR :8080 监听地址
SIGNAL_JWT_SECRET 必填,JWT 签名密钥;未设置时服务启动失败
SIGNAL_ADMIN_KEY 管理 API 密钥(可选)
SIGNAL_ALLOWED_ORIGINS CORS Origin 白名单(逗号分隔)
SIGNAL_MAX_MSG_BYTES 65536 WebSocket 单消息上限(字节)
SIGNAL_WS_PING_INTERVAL 10 心跳间隔(秒)
SIGNAL_WS_PONG_WAIT 25 心跳超时(秒)
SIGNAL_WS_RPS / SIGNAL_WS_BURST 20 / 40 每连接速率限制
SIGNAL_REDIS_ENABLED false 启用 Redis 多节点扩展
SIGNAL_REDIS_ADDR localhost:6379 Redis 地址

完整列表见 env.example