webman是php高性能常驻进程web框架,非python框架;必须用composer create-project workerman/webman安装,禁用pip install等错误方式,且需绑定订单驱动型会话模型、消息落库、websocket与订单状态联动、事务兜底等医疗合规要求。

Webman 不是 Python 框架,也不是基于 PHP 的 CMS;它是一个 **PHP 高性能常驻进程 Web 框架**(类似 Swoole + Laravel Octane 的定位),2.2.0 版本起深度整合协程、连接池与 TCP/UDP 服务。你如果按 Python 教程执行 pip install webman,会失败——根本不存在这个 PyPI 包。
要构建高性能在线问诊系统,必须从技术栈真实性和并发模型出发,而不是套用错误框架文档。
确认 Webman 实际技术栈和安装方式
Webman 是 PHP 生态的 Composer 包,不是 Python 工具。所有「pip install webman」「webman createproject」类命令均属虚构或混淆(可能源自对 Django/Flask 或某国产低代码平台的误传)。
真实安装方式只有:
- 确保 PHP ≥ 8.0,已启用
swoole扩展(推荐 5.0+) - 运行:
composer create-project webman/console my-consultation - 启动:
php start.php start -d(非python app.py)
任何要求你装 webman Python 包、或用 webman createapp 命令的教程,底层已脱离 Webman 官方实现,不可用于生产问诊系统。
问诊系统必须绑定「订单驱动型会话」模型
医疗场景下,聊天不是 IM,而是带生命周期、审计要求、状态机约束的服务单元。Webman 的协程能力适合处理高并发订单轮询,但数据模型必须独立设计,不能依赖框架“自动关联”。
关键表必须存在且强约束:
-
consultation_order:含status(WAITING/ONGOING/FINISHED/CANCEL)、start_time、end_time、patient_id、doctor_id -
consultation_message:每条消息必须存order_id、sender_role(PATIENT/DOCTOR)、msg_type(TEXT/IMAGE/FILE)、created_at - 禁止用内存级聊天室(如
Swoole\WebSocket\Server单纯广播),所有消息落库后才推送前端
否则无法满足《互联网诊疗监管办法》中“可追溯、可还原、存储≥15年”的硬性要求。
WebSocket 连接必须与订单状态实时联动
Webman 支持原生 WebSocket 服务,但默认不校验业务状态。若患者已取消订单,对应 WebSocket 连接仍保持活跃,就会造成医生端收到无效消息或资源泄漏。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
正确做法是在 onOpen 和 onMessage 中主动查库:
- 用户连接时,解析 token 获取
user_id和角色,再查其当前是否有status = ONGOING的consultation_order - 每次发消息前,再次校验该订单是否仍为
ONGOING,否则拒绝写入并关闭连接 - 使用
ConnectionPool管理数据库连接,避免协程间连接争用
示例伪代码逻辑:
public function onMessage($server, $frame) {
$order = Db::table('consultation_order')
->where('id', $this->order_id)
->where('status', 'ONGOING')
->first();
if (!$order) {
$server->close($frame->fd);
return;
}
// 继续存消息、通知对方...
}
异步任务不能替代事务一致性
Webman 2.2.0 增强了异步任务(Task 组件),但问诊中的关键操作——如“支付成功 → 启动订单 → 推送医生”——必须用数据库事务兜底,而非靠队列重试。
常见错误:
- 把支付回调逻辑全丢进异步任务,导致支付成功但订单未创建、医生未收到通知
- 用 Redis 计数器代替数据库行锁,引发超卖(例如同一医生被两个患者同时抢到)
正确姿势:
- 支付回调入口用
Db::transaction()包裹订单创建 + 状态更新 + 消息插入 - 仅将「发短信」「推极光通知」「生成病历 PDF」等非核心步骤放入异步任务
- 医生接单动作需
SELECT ... FOR UPDATE锁住目标订单行,防止并发冲突
性能瓶颈不在协程数量,而在事务粒度是否合理、锁范围是否最小化。
Webman 确实能扛住万级问诊并发,但前提是放弃“框架帮你搞定一切”的幻想——它的高性能来自你对协程生命周期、连接池边界、数据库事务边界的精确控制。最容易被忽略的,是把医疗合规要求(如消息必落库、订单状态机)当成可选功能,而它们恰恰是压垮高并发系统的最后一根稻草。









