基本環(huán)境:
workerman4
gateway-worker3
gatewayclient3
laravel5.8
最近接到新需求,使用workerman接收前端通信數(shù)據(jù)轉(zhuǎn)發(fā)給第三方,這是一個(gè)實(shí)時(shí)轉(zhuǎn)發(fā)流程,全程采用ws協(xié)議,數(shù)據(jù)類型二進(jìn)制的binary message。
新手剛接觸這個(gè)WK,使用Laravel中的wk例子,基本都是照著例子或者技術(shù)先鋒們的筆記借鑒,目前前端與wk服務(wù)端可實(shí)時(shí)通信交互。
涉及到外部服務(wù)端,想法是:當(dāng)前端發(fā)起ws請(qǐng)求,立馬在Events中,在onConnect()中采用AYSN異步類進(jìn)行ws協(xié)議鏈接第三方,達(dá)到一個(gè)長(zhǎng)鏈接目的,設(shè)置websocketType=BINARY_TYPE_ARRAYBUFFER,但是在這里不清楚如何將這異步send和onMessage轉(zhuǎn)發(fā)給對(duì)應(yīng)前端,有些迷茫。
隨后 將這半吊子的實(shí)例丟進(jìn)web服務(wù)端,只能onconnect,onwensocket 無(wú)反應(yīng)。端口開啟2300-2305
代碼如下,請(qǐng)多多指正:
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');
//針對(duì) Windows 一次執(zhí)行,無(wú)法注冊(cè)多個(gè)協(xié)議的特殊處理
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'; // 分布式時(shí),填寫內(nèi)網(wǎng)真實(shí)IP
$gateway->startPort = 2300;
$gateway->pingInterval = 30; // 心跳時(shí)間
$gateway->pingNotResponseLimit = 0; // 1 - 客戶端發(fā)送心跳; 0 - 服務(wù)端發(fā)送心跳
$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'); // 注冊(cè)監(jiān)聽
}
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)) {
// //定時(shí)發(fā)送消息
// $con->timer = Timer::add(0.04, function () use ($con) {
// $con->send();
// });
// }
// $con->send('websocket 連接成功');
};
$ws_connection->onError = function($connection, $code, $msg){
echo "錯(cuò)誤:$msg\n";
};
$ws_connection->onClose = function($connection){
echo '鏈接關(guān)閉';
// $connection->reConnect(1);
};
$ws_connection->connect();
self::$ws_server = $ws_connection;
}
/**
* 客戶端websocket消息 可以做鑒權(quán)業(yè)務(wù)
* @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'); // 暫時(shí)語(yǔ)音文件讀取替代前端通信數(shù)據(jù)$messageJson
$file = file_get_contents($filePath);
$fdata = substr($file,0, 1280);
self::$ws_server->websocketType = Websocket::BINARY_TYPE_BLOB;
self::$ws_server->send($fdata);// 異步轉(zhuǎn)發(fā) $messageJson
// self::$ws_server->send('{"end":true}');
self::$ws_server->onMessage = function($connection, $data){
echo '遠(yuǎn)程服務(wù)器消息';
echo $data;
$connection->connect();// 這步鏈接這么寫不清楚對(duì)不對(duì)
//self::sendMessage(200, '{"你好,歡迎到來(lái)"}', $data); // 將第三方返回的通信數(shù)據(jù)轉(zhuǎn)發(fā)前端
};
//self::pushFwrite($messageJson); 測(cè)試是否內(nèi)容正常返回
echo '客戶端消息:'.$messageJson;
self::log(__FUNCTION__, $clientId, $messageJson);
}
得到的第三方鏈接started回復(fù),但是之后就是異常問題, 所以不太清楚是代碼鏈接流程有問題還是設(shè)置的數(shù)據(jù)類型有問題。第一次弄那么復(fù)雜的技術(shù)業(yè)務(wù),身邊也沒有這方面朋友交流,網(wǎng)上帖子大多都是前端與WK通信交互的實(shí)例。
以上是本人的不成熟代碼,還請(qǐng)各位技術(shù)大佬多多指點(diǎn),非常感謝您的慷慨解囊!??!