Workerman 不能直接实现语音同声传译,因其仅为 PHP 网络通信框架,无音频处理能力,不支持麦克风访问、WebRTC 解析及 ASR/TTS 模块;所有语音识别、翻译、合成必须交由外部独立服务(如 Python FastAPI + Whisper)完成,Workerman 仅负责按用户语言偏好路由并推送文本。

Workerman 不能直接实现视频会议里的「语音同声传译」,它只负责文本消息的实时分发;真正的语音识别(ASR)、翻译(MT)、语音合成(TTS)必须由外部服务完成,Workerman 的角色是把翻译后的文本按语言偏好推送给对应客户端。
为什么不能在 Workerman 里做语音识别和翻译
Workerman 是纯 PHP 的网络通信框架,不带音频处理能力:它无法访问麦克风、不支持 WebRTC 音频流解析、也没有内置 ASR/TTS 模块。试图在 onMessage 里调用 shell_exec('whisper audio.wav') 会阻塞事件循环,导致连接堆积甚至崩溃。所有耗时操作(语音转文字、文字翻译、生成字幕)必须卸载到独立服务——比如 Python 的 FastAPI + Whisper + Transformers,再通过 HTTP 或 Redis 与 Workerman 协作。
如何把翻译文本按语言推给不同参会者
关键不是“推送”,而是“路由”:同一个会议里,中文用户该看中文字幕,英文用户该看英文字幕,不能全量广播原始翻译结果。必须在连接建立后绑定用户语言,并在推送前查表路由。
- 用户登录后,前端在 WebSocket 连接成功时主动发送初始化消息:
{"type":"bind_lang","lang":"en_US"} - Workerman 的
onMessage中解析该消息,将$connection->id与$lang存入内存数组或 Redis,键为conn:lang:{$connection->id} - 当收到翻译服务发来的字幕(例如 via HTTP POST 到
/api/push/caption),先查参会者列表,再逐个查其语言,调用$connection->send($translated_text)分别推送 - 避免用
$worker->connections全量遍历——如果会议有 500 人但只有 20 人听英文,就只推这 20 个连接
Webman + Workerman 混合项目里最容易漏掉的配置点
如果你用 Webman 处理 HTTP 接口(如接收 ASR 结果)、Workerman 处理 WebSocket 推送,二者语言包不能共用:
- Webman 的
lang/en_US.php是闭包加载、依赖Request实例,Workerman 进程里app()和request()都不存在 - 错误做法:在 Workerman 的回调里直接
use App\Support\I18n; I18n::trans('caption_start', $lang)—— 会报Call to a member function getLocale() on null - 正确做法:把 Webman 的语言文件导出为扁平数组,如
resources/lang/export/en_US.php返回return ['caption_start' => 'Live caption started'];,Workerman 启动时require_once加载进全局变量 - Redis 不是必须项,小规模会议用 PHP 内存数组(
static $langMap = [];)更轻量;但需注意多进程间不共享,GatewayWorker 架构下推荐用 Redis
真正难的不是推送动作本身,而是语言上下文的生命周期管理:用户中途切换语言怎么办?断线重连后语言标识是否丢失?这些状态必须比连接更持久,且不能依赖浏览器 localStorage 或 cookie——因为 Workerman 看不到 HTTP 上下文。

















