如何在gatewayWorker的onConnect方法中获取到当前客户端连接

liong

问题描述

使用的是gatewayWorker,
BusinessWorker设置了自定义的业务处理类
$worker = new BusinessWorker();
$worker->eventHandler = \App\GatewayWorker\Events::class;

Events类代码:

<?php
namespace App\GatewayWorker;
use GatewayWorker\Lib\Context;
use GatewayWorker\Lib\Gateway;
use Workerman\Connection\AsyncTcpConnection;
use Workerman\Connection\TcpConnection;
class Events
{
public static function onWorkerStart($businessWorker){
var_dump('启动服务');
}
public static function onConnect($client_id){
// todo 当前客户端连接 $connection
var_dump('连接成功-' . $client_id);
}
public static function onWebSocketConnect($client_id, $data){
}
public static function onMessage($client_id, $message){
}

public static function onClose($client_id){
    var_dump('断开连接-' . $client_id);
}

}

在Events类的onConnect方法中如何获取当前客户端连接

为此你搜索到了哪些方案及不适用的原因

查看了GatewayWorker\Lib\Context和GatewayWorker\Lib\Gateway和GatewayWorker\BusinessWorker
没找到直接或间接可以获取当前连接的方法和属性

312 1 0
1个回答

walkor

连接在gateway进程,Events 类运行在worker进程,Events 类里无法直接获取gateway进程里的连接对象。
你要获取连接干什么?

  • liong 2024-01-10
    // 建立本地80端口的异步连接
    $connection_to_80 = new AsyncTcpConnection('tcp://127.0.0.1:80');
    // 设置将当前客户端连接的数据导向80端口的连接
    $connection->pipe($connection_to_80);
    // 设置80端口连接返回的数据导向客户端连接
    $connection_to_80->pipe($connection);
    // 执行异步连接
    $connection_to_80->connect();

    把以上代码放到 onConnect 运行,让每个设备连接tpca后连接到tcpb, tcpb发送数据给tcpa后,tcpa再发送给设备

  • walkor 2024-01-10

    你在 start_gateway.php 里 onConnect里可以这么做

  • liong 2024-01-12

    我在tcpa服务器建立与tcpb服务器的连接
    // 当客户端连接上来时,绑定到tcpB
    // gateway 进程,这里使用Text协议,可以用telnet测试
    $gateway = new Gateway("tcp://0.0.0.0:3000");
    // gateway名称,status方便查看
    $gateway->name = 'gatewaya';
    // gateway进程数,一般设置2个就足够
    $gateway->count = 2;
    // 本机ip,分布式部署时使用内网ip
    $gateway->lanIp = '127.0.0.1';
    // 内部通讯起始端口,假如$gateway->count=2,起始端口为2900
    // 则一般会使用2900 2901 2个端口作为内部通讯端口
    $gateway->startPort = 2900;
    // 服务注册地址
    $gateway->registerAddress = '127.0.0.1:1238';

    // 当客户端连接上来时,绑定到tcpB
    $gateway->onConnect = function($connection)
    {
    $tcpb = new \Workerman\Connection\AsyncTcpConnection('tcp://0.0.0.0:3002');
    $connection->pipe($tcpb);
    $tcpb->pipe($connection);
    $tcpb->connect();
    };

    客户端连接到tcpa服器成功,
    tcp服务器a和b都能看到连接信息
    string(35) "tcpA-onConnect:7f0000010b5400000001"
    string(35) "tcpB-onConnect:7f0000010a2800000001"

    当客户端发送信息给tcp服务器a,没有接到信息
    tcp服务器b能接收到信息

    为何tcp服务器a的不能接收到信息,是因为cp服务器a的start_gateway.php设置了以下代码导致的吗

    $gateway->onConnect = function($connection)
    {
    $tcpb = new \Workerman\Connection\AsyncTcpConnection('tcp://0.0.0.0:3002');
    $connection->pipe($tcpb);
    $tcpb->pipe($connection);
    $tcpb->connect();
    };

  • liong 2024-01-12

    目的:
    客户端发送消息给tcpa,tcpa能接收到,tcpb也能接收到

  • liong 2024-01-12

    还有一个问题,客户端开连接后,tcpb的onClose能监听到,tcpa的onClose能监听不到
    目的:
    客户端发送的消息,tcpa和tcpb都监听到
    客户端断开连接后,tcpa和tcpb都监听到

  • walkor 2024-01-12

    如果你只做转发的话,用workerman吧。gateway不支持pipe这种机制

  • liong 2024-01-12

    好的
    明天试试

  • liong 2024-01-12

    感谢大佬

  • liong 2024-01-15

    用workerman也是一样的
    Press Ctrl+C to stop. Start success.
    string(22) "tcpA启动123-10:05:01"
    string(16) "tcpA设备连接"

    string(10) "tcpB启动"
    string(16) "tcpB设备连接"
    string(22) "tcpB收到消息--aTob"
    string(17) "tcpB:断开连接"

  • liong 2024-01-15

    tcpa代码
    <?php
    use Workerman\Worker;
    use Workerman\Connection\TcpConnection;
    use Workerman\Connection\AsyncTcpConnection;
    require_once __DIR__ . '/vendor/autoload.php';
    $worker = new Worker("tcp://0.0.0.0:3000");
    $worker->count = 1;

    $worker->onWorkerStart = function(Worker $worker)
    {
    var_dump('tcpA启动123-'.date('H:i:s'));
    };
    // tcp连接建立后
    $worker->onConnect = function(TcpConnection $connection)
    {
    var_dump('tcpA设备连接');
    // 建立本地80端口的异步连接
    $connection_to_80 = new AsyncTcpConnection('tcp://127.0.0.1:3001');
    // 设置将当前客户端连接的数据导向80端口的连接
    $connection->pipe($connection_to_80);
    // 设置80端口连接返回的数据导向客户端连接
    $connection_to_80->pipe($connection);
    // 执行异步连接
    $connection_to_80->connect();
    };
    // 当客户端发来数据时
    $worker->onMessage = function(TcpConnection $connection, $data)
    {
    var_dump('tcpA收到消息--'.$data);
    // 向客户端发送hello $data
    //$connection->send('hello ' . $data);
    };

    $worker->onClose = function(TcpConnection $connection)
    {
    var_dump('tcpA:断开连接');
    };

    // 运行worker
    Worker::runAll();

  • liong 2024-01-15

    tcpb代码
    <?php
    use Workerman\Worker;
    use Workerman\Connection\TcpConnection;
    require_once __DIR__ . '/vendor/autoload.php';
    $worker = new Worker("tcp://0.0.0.0:3001");
    $worker->count = 1;

    $worker->onWorkerStart = function(Worker $worker)
    {
    var_dump('tcpB启动');
    };
    $worker->onConnect = function(TcpConnection $connection){
    var_dump('tcpB设备连接');
    };
    // 当客户端发来数据时
    $worker->onMessage = function(TcpConnection $connection, $data)
    {
    var_dump('tcpB收到消息--'.$data);
    // 向客户端发送hello $data
    //$connection->send('hello ' . $data);
    };

    $worker->onClose = function(TcpConnection $connection)
    {
    var_dump('tcpB:断开连接');
    };

    // 运行worker
    Worker::runAll();

  • liong 2024-01-15

    收到消息和断开连接,只有tcpb能监听到

  • walkor 2024-01-15

    pipe会覆盖$worker->onMessage $worker->onClose方法,用了pipe后$worker->onMessage $worker->onClose就不会生效了

  • liong 2024-01-15

    客户端是自己的
    tcpa是自己的
    tcpb服务器是别人的

    每个客户端和tcpa的连接状态通过tcpa连接tcpb要保持一致
    每个客户端的数据经过tcpa转发个tcpb,tcpa要处理
    tcpb发数据给tcpa,然后由tcpa发送给客户端
    https://www.workerman.net/doc/workerman/async-tcp-connection/construct.html 这个试过,行不通
    还有其他可行的方案吗

🔝