跳到正文

集成与排障

调用示例

Node.js 测试客户端

仓库内 request-asr.js 用原生 net + crypto 模拟一个最小的 WebSocket 客户端,按本协议发送 models/sherpa-onnx-sense-voice/test_wavs/zh_vad.wav 的 PCM16 数据:

powershell
node .\request-asr.js

脚本会打印每一条收到的 JSON 事件(partial + final)。如需验证“发完语音后 不发空二进制帧、不关闭 WebSocket,等待服务端 idle final”的兜底链路:

powershell
node .\request-asr.js --idle

可通过 ASR_HOSTASR_PORTASR_WS_PATHASR_WS_SUBPROTOCOL 指定连接 目标;--idle 默认只发送前 2500ms 音频,也可用 ASR_MAX_AUDIO_MS 覆盖; ASR_TRAILING_SILENCE_MS 可额外发送一段 PCM 静音帧,模拟上游停说后仍持续 推空音频的情况。

FreeSWITCH 集成(mod_audio_fork)

bash
uuid_audio_fork <call_uuid> start ws://127.0.0.1:10096/audio mono 16k metadata.json

callflow-esl 默认通过 config.json 中的 audioFork.wsUrl 指向该服务:

json
{
  "audioFork": {
    "wsUrl": "ws://192.168.2.246:10096/audio",
    "bugName": "callflow_asr",
    "mixType": "mono",
    "sampleRate": "16k"
  }
}

业务通过 ctx.hear({ ... }) 触发一轮识别,runtime 内部负责 audio_fork 启停与本服务的 transcription 事件订阅。

排查识别问题

打开上行音频录制:

json
{
  "recording": {
    "enabled": true,
    "dir": "recordings"
  }
}

开启后,每个 WebSocket 会话会把收到的 16kHz 单声道 PCM16 二进制音频 保存为一个 .wav 文件。recording.dir 支持绝对路径,相对路径按配置 文件所在目录解析。服务会自动创建目录,文件名格式:

text
asr-<YYYYMMDD-HHMMSS-mmm>-<serverSessionId>[-<channelUuid>].wav

也可逐步打开调试日志:

  • logging.debugTextFrames:每条 metadata / 额外文本帧落日志
  • logging.debugAudioFrames:每个二进制帧附识别状态摘要(高吞吐场景请谨慎)
  • logging.debugRecognitionState:每次识别状态变化都落日志(适合定位 final 缺失)

日志

所有日志以 [sherpa_asr_online_server] 前缀输出到 stdout。关键事件:

  • listening on <host>:<port> ...:启动配置摘要
  • service ready; press Ctrl+C to stop. ...:启动完成提示
  • ws-<n> websocket session started on worker=<i>:握手完成
  • ws-<n> metadata=...:收到 metadata
  • ws-<n> hotwordProfile selected id=<profile>:当前连接启用指定 hotword profile
  • ws-<n> warning invalid hotwordProfile=... hotwords_disabled=true:metadata 指定了不存在或不合法的 profile,本连接继续运行但不启用 hotwords
  • ws-<n> final text=...:发出 final
  • ws-<n> flush reason=...:触发 flush 时附原因
  • ws-<n> recording inbound audio wav=...:开始落盘
  • ws-<n> saved inbound audio wav=... bytes=...:录音文件结算

注意事项

  • 当前实现只支持 16kHz / mono / PCM16 上行音频,不做自动重采样
  • 不支持 WebSocket 帧分片
  • 模型加载耗时 1~3 秒/个,预热池规模影响启动时间
  • 每个连接会绑定一个 ASR session,会话结束后会尝试 ResetSession() 归还池中,复用失败的 session 会被丢弃
  • 服务没有平滑关闭:Ctrl+C 会直接终止 accept 与工作线程
  • 当前没有鉴权、没有限流(除 concurrency.maxSessions),建议仅在内网 / 可信网络运行

文档与代码在同一仓库维护,现有 Markdown 是唯一内容源。