用 PHP 实现 WebSocket 服务

聊天室、游戏等场景躲避不了服务器主动下发消息。通常 PHP 的生命周期都是在一个 HTTP 请求结束之后就会跟着结束,在连接没有断开的情况下,一个请求就会咬住一个进程不放开。这种情况用阻塞 HTTP 请求来等待服务器下发消息就显得很蠢。不过作为世界上最好的语言,PHP 当然是有解的,Hostker 为开发者实现了 WebSocket 服务。

WebSocket 是基于 HTTP 的一个协议,用于双向的实时通讯,以下简称 WS 服务。由于需要启动进程监听一个特定的端口,还需要高性能的服务支撑,我们选择了 Swoole 扩展进行开发。Swoole 是一个 Server 框架,实现了多进程、事件驱动、异步、Task 等功能。

启动 WS 服务之后,主进程会读取 Hostker 上面所有开通了 WS 服务的 APP 对应配置并保存在可共享的内存中,同时派生出一定数量的 Worker 进程和 Task 进程。

当 PHP 需要主动推送消息时,会通过一个内部接口将消息发给 WS 主进程,主进程会根据 Worker 的繁忙程度投递到最闲的 Worker 进程,Worker 会对这一请求进行分析,单发、群发、鉴权等,没有问题的话异步投递给 Task 任务进行消息推送。

当用户连接或者断开 WS 时,主进程同样会根据繁忙程度选择 Worker 进程进行绑定,并异步投递给 Task 任务通知给 PHP。

有开发者申请开通或者关闭 WS 服务的时候,内部会通过一个接口更新到共享内存中,供 Task 任务和 Worker 进程鉴权使用。

Task 任务作用就是上面提到的两个,下发消息和回报上下线状态,在接到新任务之后会立即执行。

至此,本博客的主线内容全部更新完毕。今后会根据情况不定期更新一些技术内容。

《用 PHP 实现 WebSocket 服务》上有6条评论

      1. The WebSocket Protocol is an independent TCP-based protocol. Its only relationship to HTTP is that its handshake is interpreted by HTTP servers as an Upgrade request,基于 HTTP 的说法不够准确吧

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.