多协议支持

需求

有时我们需要一套应用程序支持多个客户端,进而需要应用支持多个协议。例如一个IM即时通讯应用,可能需要同时支持浏览器使用,又要支持移动App客户端。而二者所使用的协议可能完全不同。

如何支持多协议

在WorkerMan中最简单的实现方法是开启多个端口,每个端口使用一种协议。不同客户端使用各自的协议去连特定的端口。

示例(小蝌蚪)

小蝌蚪应用程序是运行在PC浏览器里面的,使用Websocket协议与WorkerMan通讯,当我们需要把它移植到手机App上却没有合适的客户端Websocket库时,我们可以使用更简单的协议来实现App与WorkerMan通讯,例如Text文本协议(协议规则为 文本+换行符)。

下面是开启多端口支持多协议示例

创建新文件 Applications/Todpole/start_text_gateway.php

  1. use \Workerman\Worker;
  2. use \GatewayWorker\Gateway;
  3. // 自动加载类
  4. require_once __DIR__ . '/../../Workerman/Autoloader.php';
  5. // ##########新增端口支持Text协议 开始##########
  6. // 新增8283端口,开启Text文本协议
  7. $gateway_text = new Gateway("Text://0.0.0.0:8283");
  8. // 进程名称,主要是status时方便识别
  9. $gateway_text->name = 'TodpoleGatewayText';
  10. // 开启多少text协议的gateway进程
  11. $gateway_text->count = 4;
  12. // 本机ip(分布式部署时需要设置成内网ip)
  13. $gateway_text->lanIp = '127.0.0.1';
  14. // 设置服务注册地址(注意:这个地址是start_register.php中监听的地址)
  15. $gateway_text->registerAddress = '127.0.0.1:1237';
  16. // gateway内部通讯起始端口,起始端口不要重复
  17. $gateway_text->startPort = 2500;
  18. // 也可以设置心跳,这里省略
  19. // ##########新增端口支持Text协议 结束##########
  20. if(!defined('GLOBAL_START'))
  21. {
  22. Worker::runAll();
  23. }

重新启动

测试效果

由于是Text文本协议,我们可以通过telnet命令方便的模拟文本协议客户端。以下运行telnet命令的结果

  1. telnet 127.0.0.1 8283
  2. Trying 127.0.0.1...
  3. Connected to 127.0.0.1.
  4. Escape character is '^]'.
  5. {"type":"update","id":156,"angle":3.636,"momentum":0,"x":-64.8,"y":147.1,"life":1,"name":"Guest.156","authorized":false}
  6. {"type":"update","id":156,"angle":4.27,"momentum":0,"x":-64.8,"y":147.1,"life":1,"name":"Guest.156","authorized":false}
  7. {"type":"update","id":156,"angle":5.766,"momentum":0,"x":-64.8,"y":147.1,"life":1,"name":"Guest.156","authorized":false}
  8. {"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的多协议也是同样的道理

支持多协议还有其他的方法,比如通过协议自身的特点区分当前是哪种协议,然后分别调用相应协议的解码方法,这样可以做到只开一个端口就可以支持多种协议的效果