多协议支持
需求
有时我们需要一套应用程序支持多个客户端,进而需要应用支持多个协议。例如一个IM即时通讯应用,可能需要同时支持浏览器使用,又要支持移动App客户端。而二者所使用的协议可能完全不同。
如何支持多协议
在WorkerMan中最简单的实现方法是开启多个端口,每个端口使用一种协议。不同客户端使用各自的协议去连特定的端口。
示例(小蝌蚪)
小蝌蚪应用程序是运行在PC浏览器里面的,使用Websocket协议与WorkerMan通讯,当我们需要把它移植到手机App上却没有合适的客户端Websocket库时,我们可以使用更简单的协议来实现App与WorkerMan通讯,例如Text文本协议(协议规则为 文本+换行符)。
下面是开启多端口支持多协议示例
创建新文件 Applications/Todpole/start_text_gateway.php
use \Workerman\Worker;
use \GatewayWorker\Gateway;
// 自动加载类
require_once __DIR__ . '/../../Workerman/Autoloader.php';
// ##########新增端口支持Text协议 开始##########
// 新增8283端口,开启Text文本协议
$gateway_text = new Gateway("Text://0.0.0.0:8283");
// 进程名称,主要是status时方便识别
$gateway_text->name = 'TodpoleGatewayText';
// 开启多少text协议的gateway进程
$gateway_text->count = 4;
// 本机ip(分布式部署时需要设置成内网ip)
$gateway_text->lanIp = '127.0.0.1';
// 设置服务注册地址(注意:这个地址是start_register.php中监听的地址)
$gateway_text->registerAddress = '127.0.0.1:1237';
// gateway内部通讯起始端口,起始端口不要重复
$gateway_text->startPort = 2500;
// 也可以设置心跳,这里省略
// ##########新增端口支持Text协议 结束##########
if(!defined('GLOBAL_START'))
{
Worker::runAll();
}
重新启动
测试效果
由于是Text文本协议,我们可以通过telnet命令方便的模拟文本协议客户端。以下运行telnet命令的结果
telnet 127.0.0.1 8283
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
{"type":"update","id":156,"angle":3.636,"momentum":0,"x":-64.8,"y":147.1,"life":1,"name":"Guest.156","authorized":false}
{"type":"update","id":156,"angle":4.27,"momentum":0,"x":-64.8,"y":147.1,"life":1,"name":"Guest.156","authorized":false}
{"type":"update","id":156,"angle":5.766,"momentum":0,"x":-64.8,"y":147.1,"life":1,"name":"Guest.156","authorized":false}
{"type":"update","id":156,"angle":6.284,"momentum":3,"x":-58.8,"y":146.7,"life":1,"name":"Guest.156","authorized":false}
我们能看到其它PC客户端通过WorkerMan转发来的蝌蚪的实时坐标数据,我们也可以输入自己的坐标数据,然后按回车键,我们就能在小蝌蚪界面上看到自己了。这样通过使用telnet客户端+文本协议,我们可以方便的调试数据,开发新的客户端了。
说明:
以上是WorkerMan多协议支持示例,我们看到只需要简单的初始化端口及协议即可,服务端的业务代码不用任何更改。开发者也可以使用其它协议初始化端口,也可以参考《定制通讯协议章节》定义自己的协议
以上是Gateway/Worker模型的多协议支持示例,基于Worker的多协议也是同样的道理
支持多协议还有其他的方法,比如通过协议自身的特点区分当前是哪种协议,然后分别调用相应协议的解码方法,这样可以做到只开一个端口就可以支持多种协议的效果