Gateway监听多个端口(每个端口的协议不同)时,不能同时工作

kenny534

如题:只有第一个端口(9526)可以触发Events的onMessage方法,而9527端口只能连接上,onMessage不会被调用到

$register = new Register('text://0.0.0.0:1237');

//初始化 bussinessWorker 进程
$worker = new BusinessWorker();
// worker名称
$worker->name = 'AppBusinessWorker';
// bussinessWorker进程数量
$worker->count = 2;
// 服务注册地址
$worker->registerAddress = '192.168.18.9:1237';
//设置处理业务的类,此处制定Events的命名空间
$worker->eventHandler = 'app\kenny\controller\Events';

// 初始化 gateway 进程
$gateway = new Gateway("book://0.0.0.0:9526");
// 设置名称,方便status时查看
$gateway->name = 'AppGateway';
$gateway->count = 1;
// 分布式部署时请设置成内网ip(非127.0.0.1)
$gateway->lanIp = '192.168.18.9';

$gateway->startPort = 2300;
// 心跳间隔
$gateway->pingInterval = 180;
$gateway->pingNotResponseLimit = 1;
// 心跳数据
$gateway->pingData = "\n|\n";
// 服务注册地址
$gateway->registerAddress = "192.168.18.9:1237";

$gateway->onWorkerStart = function ($gateway){
    if ($gateway->id === 0){ //仅在第二个gateway中监听websocket
        $inner_gateway = new Gateway("text://0.0.0.0:9527");
        $inner_gateway->reusePort = true;
        $inner_gateway->listen();
    }
};

//运行所有Worker;
Worker::runAll();

请问这是GatewayWorker模型的设计所致,还是哪里使用的不对头?

4776 4 0
4个回答

kenny534

追问一下:GatewayWorker是否可以实现协议之间的通讯?
例如:开启两个gateway : gateway1(text协议) 和 gateway2(websocket) ,实现在两个端口上监听。
在gateway1 接收消息,再从gateway2发送出去,或者从gateway2收到消息,再发到gateway1上去,当然,这就涉及到“协议间通讯”的问题了。请问是否能够支持呢?

  • 暂无评论
walkor

http://doc2.workerman.net/multi-protocols.html
多协议支持请参考手册

  • kenny534 2019-09-17

    能否在onMessage回调中增加一个“协议名称”的参数,用于识别当前数据是哪个协议下发来的,而不是通过判断数据的结构特点先识别出协议,再调用该协议下的decode方法?
    如果有这个参数的话,那么 onMessage里可以让代码简化一些,例如:
    if ($protocol == 'text' ) {
    $message = text::decode($buffer);
    }
    if ($protocol == 'websocket' ){
    $message = websocket::decode($buffer);
    }
    //上述代码应该不能正常运行,是伪代码。
    https://wenda.workerman.net/question/57
    这个链接中的方法需要判断$buffer的格式来识别协议,当前的版本如果要实现我的上述想法,应该怎么做?框架是否可以考虑增加一个可选参数,比如叫 $protocol ?

  • walkor 2019-09-17

    协议是和端口绑定的,可以通过端口来判断协议类型。参考手册 http://doc2.workerman.net/get-gateway-port.html

  • kenny534 2019-09-17

    怎样才能调用到协议的decode/encode方法呢?我写的那小段运行报错。

  • kenny534 2019-09-17

    1:
    在gateway3.0.13下,无法像(https://wenda.workerman.net/question/57)文中提到的
    $message = yourIOSProtocol::decode($buffer);
    这样调用自定义协议的解码方法,如果用require '..../yourIOSProtocol.php',又会报重复定义的错误。烦请给一个示例
    2:
    《多协议支持》章节最底部的说明:
    /支持多协议还有其他的方法,比如通过协议自身的特点区分当前是哪种协议,然后分别调用相应协议的解码方法,这样可以做到只开一个端口就可以支持多种协议的效果/
    如何实现“分别调用相应协议的解码方法”呢?调用之后,怎样找到对端,将数据发出去。

  • latin 2019-09-18

    多协议用群主发的文档的方式不用调用协议的decode/encode方法啊,怎么感觉你搞复杂了。

blogdaren

使用姿势不正确, 原因是 gateway的用户回调onWorkerStart 的内部端口此时并不能与bussinessworker建立连接,按官方手册方法玩吧,非要这么用的话,参考代码:


$gateway->onWorkerStart = function($gateway){
    if ($gateway->id === 0)
    {
        //step-1
        $inner_gateway = new Gateway("text://0.0.0.0:9527");
        $inner_gateway->reusePort = true;
        $inner_gateway->lanIp = '127.0.0.1';
        $inner_gateway->startPort = 3900;
        $inner_gateway->lanPort = $inner_gateway->startPort + $gateway->id;
        $inner_gateway->registerAddress = ;
        $inner_gateway->onConnect  = array($inner_gateway, 'onClientConnect');
        $inner_gateway->onClose = array($inner_gateway, 'onClientClose');
        $inner_gateway->onMessage = array($inner_gateway, 'onClientMessage');
        $inner_gateway->listen();

        //step-2
        $worker = new Worker("GatewayProtocol://{$inner_gateway->lanIp}:{$inner_gateway->lanPort}");
        $worker->name = 'testWorker';
        $worker->onMessage = array($inner_gateway, 'onWorkerMessage');
        $worker->onConnect = array($inner_gateway, 'onWorkerConnect');
        $worker->onClose   = array($inner_gateway, 'onWorkerClose');
        $worker->listen();

        //step-3
        $inner_gateway->registerAddress();
    }
};
  • 暂无评论
kenny534

谢谢两位的回复,继续学习……

  • 暂无评论
年代过于久远,无法发表回答
🔝