适用于 2026-10 在线授权 Linux 包 r3。服务端只暴露一个 WebSocket 聚合入口;4 个测量 Worker 位于容器内部。
部署方在服务器上查看业务令牌(容器名与路径以实际部署为准):
docker exec <容器名> cat /license-state/business-token # 在线授权包通常为 /license-state/business-token; # 其他部署以实际挂载为准(用 docker inspect 查看 Mounts)
USBKey/本地 P1:令牌位于 /var/lib/emotion_hr/installations/emotion_hr/security/business-token;Linux/RK 安装器会把 token 注入 /opt/emotion-hr/client/ws_config.json,Windows 注入 %LOCALAPPDATA%\EmotionHR\client\ws_config.json。本地安装同样必须带 token。
客户端必须携带:
Authorization: Bearer <business-token>
凭据优先放在 Authorization 头。?token= 是兼容浏览器/分享链接的回退;服务端设置 EMOTION_REQUIRE_AUTH_HEADER=1 后关闭,硬化启动脚本 start-lease.sh 会开启。未开启时 query 仍可用。
这是部署令牌,不是用户账号 access token。公网部署必须使用 WSS 反向代理并在代理层限制来源。
Web 控制台的“实时监测分享”链接是云端访客令牌(guest_share),仅由云端网关校验;私有化 9100 只接受 business-token 或 ehr1。
私有化部署不希望向前端或临时客户端下发长期 business-token 时,由客户网关用 business-token 签发 ehr1:有效期 1–300 秒,到期服务端会关闭连接,需重新签发并重连。
python3 security_runtime.py create-video-credential \ --subject user-123 --ttl 120 \ --token-file /var/lib/emotion_hr/installations/emotion_hr/security/business-token
客户端把签发的值放进请求头,不要放进 URL query:
Authorization: Bearer ehr1.<body>.<signature>
ehr1 仅用于视频连接;部署/管理操作仍使用 business-token。
每个 WebSocket 二进制消息:
byte 0 : 数据类型,0 = 视频 byte 1..8 : float64 little-endian 时间戳(秒) byte 9.. : JPEG 图像字节
以约 30 fps 发送;服务端每 30 帧返回一次 JSON 结果。建议 640×480 或 854×480,单条消息不超过 4 MB。
import asyncio, json, struct, time
import cv2
from websockets.legacy.client import connect
TOKEN = "<business-token>"
URL = "ws://<host>:9100/"
async def main():
cap = cv2.VideoCapture("face.mp4")
async with connect(URL, extra_headers={"Authorization": "Bearer " + TOKEN}, max_size=16 * 1024 * 1024) as ws:
for batch in range(20):
epoch = time.time()
for i in range(30):
ok, frame = cap.read()
if not ok:
cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
ok, frame = cap.read()
ok, jpg = cv2.imencode(".jpg", cv2.resize(frame, (854, 480)))
await ws.send(b"\x00" + struct.pack("<d", epoch + i / 30) + jpg.tobytes())
await asyncio.sleep(1 / 30)
result = json.loads(await asyncio.wait_for(ws.recv(), 120))
print(result.get("emotion_short_res"), result.get("hrv"))
asyncio.run(main())
| 字段 | 说明 |
|---|---|
emotion_short_res | 情绪分布对象(中文标签→概率,仅保留 >0.05 的项);预热阶段可能为 null。 |
age_gender | {gender, age};age 是年龄段字符串,如 "30-39"。 |
hrv | HRV 对象或 null;预热阶段为 null。含 meanHr、sdnn、rmssd、SBP、DBP、Breathing_RATE、mood_score 等。 |
hrv.SBP / hrv.DBP | 血压估算值(mmHg),不能替代血压计。 |
hrv.mood_score.stress_score / attention_score | 压力 / 专注度趋势评分。 |
spo2 | 血氧;质量和时长不足时为 null。 |
big_five_res | 需要有效 HRV 频率指标后出现。 |
info / error | 诊断信息;业务应以 error 为空且字段非空判断有效结果。 |
| 现象 | 原因 |
|---|---|
| WebSocket 1008 Invalid Token | token 不对;检查 business-token 和 Bearer 格式。 |
| HTTP 426 Upgrade Required | 用普通 HTTP 访问 WebSocket 端口,属正常。 |
| HTTP 401 | 严格模式 token 不匹配。 |
| 连接排队/HTTP 503 | Worker 都忙时,新认证连接会等待空闲 Worker;等待超过 queue-seconds 返回 503。不会替换正在测量的用户。 |
| HTTP 502 / 握手超时 | 网关到服务端不可达或服务未就绪(重启、USBKey 授权未完成);稍后重试并检查服务状态。 |
| 连接成功但无结果 | 帧率/JPEG/人脸不足;确认持续发送 30 帧/秒。 |
PORT=9100、WORKER_BASE_PORT=8001、BIND_ADDRESS=127.0.0.1;Worker 数由授权/安装配置决定,对外只有 9100 一个聚合入口。ws_config.json 的 auth_token,直接启动客户端即可。命令行自检工具(在线/USBKey 共用,内置视频,不调用摄像头):emotion-hr-verify-20261020.tar.gz
本页是 r3 在线授权接入说明。网站原有的云端 API 文档仍适用于云端账号模式;私有化部署请以本页和包内 接口说明.md 为准。