新手请教各位大佬:使用GateWay前端-Web服务端-外部服务端通信转发解决方案

美丽的角落

问题描述

基本环境:
workerman4
gateway-worker3
gatewayclient3
laravel5.8
最近接到新需求,使用workerman接收前端通信数据转发给第三方,这是一个实时转发流程,全程采用ws协议,数据类型二进制的binary message。
新手刚接触这个WK,使用Laravel中的wk例子,基本都是照着例子或者技术先锋们的笔记借鉴,目前前端与wk服务端可实时通信交互。

涉及到外部服务端,想法是:当前端发起ws请求,立马在Events中,在onConnect()中采用AYSN异步类进行ws协议链接第三方,达到一个长链接目的,设置websocketType=BINARY_TYPE_ARRAYBUFFER,但是在这里不清楚如何将这异步send和onMessage转发给对应前端,有些迷茫。

随后 将这半吊子的实例丢进web服务端,只能onconnect,onwensocket 无反应。端口开启2300-2305

代码如下,请多多指正:
class Workerman extends Command
{
//兼容win
protected $signature = 'wk
{action : action}
{--start=all : start}
{--d : daemon mode}';

protected $description = 'Start a Workerman server.';

public function handle()
{
    global $argv;
    $action = $this->argument('action');

    //针对 Windows 一次执行,无法注册多个协议的特殊处理
    if ($action === 'single') {
        $start = $this->option('start');
        if ($start === 'register') {
            $this->startRegister();
        } elseif ($start === 'gateway') {
            $this->startGateWay();
        } elseif ($start === 'worker') {
            $this->startBusinessWorker();
        }
        $this->mkdir();
        Worker::runAll();
    }  
}
 private function startBusinessWorker()
{
    $worker = new BusinessWorker();
    $worker->name = 'BusinessWorker';
    $worker->count = 1;
    $worker->registerAddress = '127.0.0.1:1236';
    $worker->eventHandler = \App\Library\Workerman\Events::class; // 可自定义命名
    }

    rivate function startGateWay()
{
    $gateway = new Gateway("websocket://0.0.0.0:8080");
    $gateway->name = 'Gateway';
    $gateway->count = 1;
    $gateway->lanIp = '127.0.0.1'; // 分布式时,填写内网真实IP
    $gateway->startPort = 2300;
    $gateway->pingInterval = 30;  // 心跳时间
    $gateway->pingNotResponseLimit = 0; // 1 - 客户端发送心跳; 0 - 服务端发送心跳
    $gateway->pingData = '{"type":"ping"}';
    $gateway->registerAddress = '127.0.0.1:1236'; // 与business 通信地址,两者一致
    $gateway->maxSendBufferSize = 2 * 1024 * 1024;
}

private function startRegister()
{
    new Register('text://0.0.0.0:1236'); // 注册监听
}

Events.php

public static $ws_server;
/**
 * 客户端连接事件
 * @param string $clientId
 * @return void
 */
public static function onConnect(string $clientId)
{
    echo "Connected\n";
    $xfHost    = self::getTransfer();
    $ws_connection = new AsyncTcpConnection($xfHost);
    $ws_connection->WebsocketPingInterval = 30;
    $ws_connection->websocketType = Websocket::BINARY_TYPE_BLOB;//BINARY_TYPE_ARRAYBUFFER
    $ws_connection->onConnect = function($connection){
        echo 'websocket connected';
    };
    $ws_connection->onWebSocketConnect = function(AsyncTcpConnection $con, $responce){
        echo $responce;
        // if (empty($con->timer)) {
        //     //定时发送消息
        //     $con->timer = Timer::add(0.04, function () use ($con) {
        //         $con->send();
        //     });
        // }
        // $con->send('websocket 连接成功');
    };
    $ws_connection->onError = function($connection, $code, $msg){
        echo "错误:$msg\n";
    };
    $ws_connection->onClose = function($connection){
        echo '链接关闭';
        // $connection->reConnect(1);
    };
    $ws_connection->connect();
    self::$ws_server = $ws_connection;
}

/**
 * 客户端websocket消息  可以做鉴权业务
 * @param string $clientId
 * @param string $messageJson
 * @return void
 */
public static function onMessage(string $clientId, string $messageJson)
{
    $data = json_decode($messageJson, true);
    if(!isset($_SESSION['uid'])){
        $_SESSION['uid'] = $data['uid'];
    }

    $filePath = resource_path('image\30s-16k.wav'); // 暂时语音文件读取替代前端通信数据$messageJson
    $file = file_get_contents($filePath);
    $fdata = substr($file,0, 1280);
    self::$ws_server->websocketType = Websocket::BINARY_TYPE_BLOB;
    self::$ws_server->send($fdata);// 异步转发 $messageJson

   // self::$ws_server->send('{"end":true}');

    self::$ws_server->onMessage = function($connection, $data){
        echo '远程服务器消息';
        echo $data;
        $connection->connect();// 这步链接这么写不清楚对不对

        //self::sendMessage(200, '{"你好,欢迎到来"}', $data); // 将第三方返回的通信数据转发前端
    };
    //self::pushFwrite($messageJson); 测试是否内容正常返回
    echo '客户端消息:'.$messageJson;
    self::log(__FUNCTION__, $clientId, $messageJson);
}

得到的第三方链接started回复,但是之后就是异常问题, 所以不太清楚是代码链接流程有问题还是设置的数据类型有问题。第一次弄那么复杂的技术业务,身边也没有这方面朋友交流,网上帖子大多都是前端与WK通信交互的实例。

以上是本人的不成熟代码,还请各位技术大佬多多指点,非常感谢您的慷慨解囊!!!

189 0 0
0个回答

🔝