情况是这样的,我希望通过某些控制器发送消息到用户,然后我就用gateway创建了一个websocket,然后前台连接这个websockt,然后我希望是能后台点击一个按钮就发送消息到用户?
<?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');
/**
* 针对 Windows 一次执行,无法注册多个协议的特殊处理
*/
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] 默认是,当前文件,可以不修改
*/
$argv[1] = $action;
// 控制是否进入 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');
}
}
我启动8035,websocket端口,然后我系统请求某个接口时候能发送消息到用户?
你不是已经把流程说完了吗
关键只能在$worker->eventHandler = EventsController::class; 这个class处理数据,或者发送数据。我是想任意地方能发送消息到连接的人那里?
你想用gatewayClient啊,任何地方都可以发的,前端连接上websocket之后会返回一个client_id,你可以直接给这个client_id发送,也可以bind_uid之后直接给uid发送
打错字了哈哈
但是我这么写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 由于目标计算机积极拒绝,无法连接。
用的是use GatewayClient\Gateway;
gatewayclient的$registerAddress改成你startRegister里的ip和端口
是的是的,需要发送时候指定一下如:Gateway::$registerAddress = '127.0.0.1:8034';
问下你说的bind_uid之后直接给uid发送,这bind_uid 是怎么用法的?
客户端连接上websocket之后,会返回client_id,你可以看下你console里的startBusinessWorker指向的EventsController类,里面有个onConnect,会给客户端返回client_id,然后可以用http带上client_id请求后端,此时就可以把client_id和你系统里的uid绑定了
行好的谢谢,Gateway::bindUid($client_id, $uid); // 绑定client_id到uid
或者你前端连接websocket的时候,把用户token之类的数据传到后端,在onWebsocketConnect方法里判断是不是你系统的用户,是的把绑定下client_id,往就可以用你系统里的id跟前端通信了,不是的话直接把当前连接close掉
行谢谢谢谢
gatewayclient
换ThinkPHP框架吧····