情況是這樣的,我希望通過某些控制器發(fā)送消息到用戶,然后我就用gateway創(chuàng)建了一個(gè)websocket,然后前臺(tái)連接這個(gè)websockt,然后我希望是能后臺(tái)點(diǎn)擊一個(gè)按鈕就發(fā)送消息到用戶?
<?php
namespace App\Console\Commands;
require_once __DIR__ . '/../../../vendor/autoload.php';
use App\Http\Controllers\Admin\EventsController;
use Illuminate\Console\Command;
use GatewayWorker\BusinessWorker;
use Workerman\Worker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
class GatewayWorkerServer extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'workerman
{action : action}
{--start=all : start}
{--d : daemon mode}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Start a Workerman server.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
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();
}
if(!defined('GLOBAL_START')) {
Worker::runAll();
}
return;
}
/**
* argv[0] 默認(rèn)是,當(dāng)前文件,可以不修改
*/
$argv[1] = $action;
// 控制是否進(jìn)入 daemon 模式
$argv[2] = $this->option('d') ? '-d' : '';
$this->start();
}
private function start()
{
$this->startGateWay();
$this->startBusinessWorker();
$this->startRegister();
if(!defined('GLOBAL_START')) {
Worker::runAll();
}
}
private function startBusinessWorker()
{
$worker = new BusinessWorker();
$worker->name = 'BusinessWorker';
$worker->count = 1;
$worker->registerAddress = '127.0.0.1:8034';
$worker->eventHandler = EventsController::class;
}
private function startGateWay()
{
$gateway = new Gateway("websocket://0.0.0.0:8035");
$gateway->name = 'Gateway';
$gateway->count = 1;
$gateway->lanIp = '127.0.0.1';
$gateway->startPort = 3000;
$gateway->pingInterval = 30;
$gateway->pingNotResponseLimit = 0;
$gateway->pingData = '{"type":"ping"}';
$gateway->registerAddress = '127.0.0.1:8034';
}
private function startRegister()
{
new Register('text://0.0.0.0:8034');
}
}
我啟動(dòng)8035,websocket端口,然后我系統(tǒng)請(qǐng)求某個(gè)接口時(shí)候能發(fā)送消息到用戶?
你不是已經(jīng)把流程說(shuō)完了嗎
關(guān)鍵只能在$worker->eventHandler = EventsController::class; 這個(gè)class處理數(shù)據(jù),或者發(fā)送數(shù)據(jù)。我是想任意地方能發(fā)送消息到連接的人那里?
你想用gatewayClient啊,任何地方都可以發(fā)的,前端連接上websocket之后會(huì)返回一個(gè)client_id,你可以直接給這個(gè)client_id發(fā)送,也可以bind_uid之后直接給uid發(fā)送
但是我這么寫try {
Gateway::sendToAll(json_encode(['type'=>'heartbeat','id'=>$id]));
} catch (\Exception $e) {
echo $e->getMessage();
}
然后直接就Can not connect to tcp://127.0.0.1:1236 由于目標(biāo)計(jì)算機(jī)積極拒絕,無(wú)法連接。
客戶端連接上websocket之后,會(huì)返回client_id,你可以看下你console里的startBusinessWorker指向的EventsController類,里面有個(gè)onConnect,會(huì)給客戶端返回client_id,然后可以用http帶上client_id請(qǐng)求后端,此時(shí)就可以把client_id和你系統(tǒng)里的uid綁定了
或者你前端連接websocket的時(shí)候,把用戶token之類的數(shù)據(jù)傳到后端,在onWebsocketConnect方法里判斷是不是你系統(tǒng)的用戶,是的把綁定下client_id,往就可以用你系統(tǒng)里的id跟前端通信了,不是的話直接把當(dāng)前連接close掉