如上图,我有个需求,就是我有个用户表,后台新增一个用户,就在workerman里为这个用户新建一个websocket链接,现在计划的是在进程启动时 先启动一个http端口,后台新增用户了就带着用户信息请求http服务,然后服务里根据传过来的用户信息为用户创建websocket链接,现在问题来了,怎么存储websocket的实例呢,搜到有人遇到同样的问题,看他是用$_SESSION,但是这个被作者说了不行
弄个类,存储在静态变量里就行了
class MyConnections { public static connections = []; }
存的时候
MyConnections::connection[标记] = $connection;
起始按照你截图的用法,存$connection没什么意义。
class Worker extends Server { protected $processes = 1; protected function init() { $ws = new \Workerman\Worker('websocket://0.0.0.0:2000'); // 启动4个进程对外提供服务 $ws->count = 1; $ws->onConnect = function (TcpConnection $connection){ }; $ws->onMessage = function (TcpConnection $connection,$data) { $connection->send('aaaa'); }; $ws->onClose = function (TcpConnection $connection) { var_dump('ws断开'); }; parent::init(); // TODO: Change the autogenerated stub } public static $i = 0; /** * http服务 * @param $connection * @param $data */ public function onMessage($connection, $data) { //pc管理后台新建用户会请求这个http服务,收到新注册用户消息,为用户创建ws链接 // var_dump($data['get']['ws_url']); $con = new AsyncTcpConnection('ws://127.0.0.1:2000'); //开始链接 $con->onConnect = function ($con) { }; //链接成功 $con->onWebSocketConnect = function (AsyncTcpConnection $connection) { $connection->uid = ++ self::$i; //1更新用户在线状态 //2启动心跳定时器 $connection->timer_id = Timer::add(10, function () use($connection) { $ping = [ 'msgId' => 122333, 'type' => 'common.topic.clientheartbeat', 'msg' => '', ]; $connection->send(json_encode($ping, JSON_UNESCAPED_UNICODE)); }); }; //收到消息 $con->onMessage = function (AsyncTcpConnection $connection, $data) { var_dump($connection->uid.':收到消息'); // $data = json_decode($data, true); // //服务端心跳 // if ($data['heartbeat']) { // return; // } // // $msgId = $data['msgId']; // switch ($data['type']) { // case 'authorize.topic.dismissnotify': // echo '解除门店授权'; // // break; // case 'product.topic.flowstatuschange': // echo '商品状态变更'; // // break; // default: // break; // } // // //回复 // $ack = [ // 'msgId' => $msgId, // 'type' => '', // 'msg' => 'ack' // ]; // $connection->send(json_encode($ack, JSON_UNESCAPED_UNICODE)); }; //链接关闭 $con->onClose = function (AsyncTcpConnection $connection) { echo 'onClose' . PHP_EOL; //1删除心跳定时器 if (isset($connection->timer_id)) { Timer::del($connection->timer_id); } //2更新用户下线状态 }; //链接失败 $con->onError = function (AsyncTcpConnection $connection, $code, $msg) { }; //链接 $con->connect(); } /** * 当连接建立时触发的回调函数 * @param $connection */ public function onConnect($connection) { } /** * 当连接断开时触发的回调函数 * @param $connection */ public function onClose($connection) { } /** * 当客户端的连接上发生错误时触发 * @param $connection * @param $code * @param $msg */ public function onError($connection, $code, $msg) { echo "error $code $msg\n"; } /** * 每个进程启动 * @param $worker */ public function onWorkerStart($worker) { } }
大佬我把代码修改成了这样 我发现客户同虽然每次都new 了 但是并没有影响到之前的链接,我开了ws服务根http服务,在http没请求一次就new AsyncTcpConnection,模拟了下我的需求,貌似这么写没啥问题,服务端能收到消息,动态新增的客户端也能收到消息。
uid应该是http请求携带的用户信息,不然可能创建无数个客户端
Event-Loop使用Event扩展
不用那个扩展,没多少用户有100个就很厉害了,一个用户就是一个门店
弄个类,存储在静态变量里就行了
存的时候
起始按照你截图的用法,存$connection没什么意义。
大佬我把代码修改成了这样 我发现客户同虽然每次都new 了 但是并没有影响到之前的链接,我开了ws服务根http服务,在http没请求一次就new AsyncTcpConnection,模拟了下我的需求,貌似这么写没啥问题,服务端能收到消息,动态新增的客户端也能收到消息。
uid应该是http请求携带的用户信息,不然可能创建无数个客户端
Event-Loop使用Event扩展
不用那个扩展,没多少用户有100个就很厉害了,一个用户就是一个门店