workerman + gateway +thinkphp 简单使用

844 阅读1分钟

doc3.workerman.net/315185 官方文档

  1. workerman 与 gateway安装
composer require workerman/workerman
composer require workerman/gateway-worker

  官网实例 点击下载 

  2. 配置

  start_gateway.php文件配置(开启gateway服务,并在注册服务注册)

<?php 

use \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
use \Workerman\Autoloader;
// 
$context = array(
    'ssl' => array(
        'local_cert'  => '/etc/pki/tls/certs/public.pem', // 或者crt文件
        'local_pk'    => '/etc/pki/tls/private/214498534070135.key',
        'verify_peer' => false
    )
);
// gateway 进程,这里使用websocket协议,这里使用了443端口,所有要加载ssl的配置,websocket://0.0.0.0:443:允许所有任何客户端使用wss协议访问
$gateway = new Gateway("websocket://0.0.0.0:443",$context);

$gateway->transport = 'ssl';
// gateway名称,status方便查看
$gateway->name = 'YourAppGateway';
// gateway进程数
$gateway->count = 4;
// 本机ip,分布式部署时使用内网ip
$gateway->lanIp = '172.31.240.231';
// 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
// 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口 
$gateway->startPort = 2900;
// 服务注册地址
$gateway->registerAddress = '172.31.240.231:1238';

// 心跳检测  15秒一次
$gateway->pingInterval = 15;

$gateway->pingNotResponseLimit = 1;
// 当pingData为空,服务器将不会向客户端发送心跳检测(为了节省服务器资源,心跳检测最好由客户端发起)
$gateway->pingData = '';

 if(!defined('GLOBAL_START')) {

   Worker::runAll();

 }

  3. start_businessworker.php(开启businessworker服务,并在注册服务注册)

<?php 
use \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
use \Workerman\Autoloader;

// bussinessWorker 进程
$worker = new BusinessWorker();
// worker名称
$worker->name = 'YourAppBusinessWorker';
// bussinessWorker进程数量
$worker->count = 4;
// 服务注册地址
$worker->registerAddress = '172.40.239.231:1238';

// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START')) {
    Worker::runAll();
}

  4. start_register.php(开启注册服务)

<?php 
use \Workerman\Worker;
use \GatewayWorker\Register;

// register 服务必须是text协议
$register = new Register('text://172.40.239.231:1238');

// 如果不是在根目录启动,则运行runAll方法
if(!defined('GLOBAL_START')) {
    Worker::runAll();
}

   5.  启动服务

    启动

    以debug(调试)方式启动

      php start.php start

    以daemon(守护进程)方式启动

      php start.php start -d

    停止

      php start.php stop

    重启

      php start.php restart

    平滑重启

      php start.php reload

    查看状态

      php start.php status

5. 客户端操作(这是我基于小程序接口,封装的一个socket库)

    var socket = new Socket('wss://wss.xinyuruiyang.com');
    socket.on("open",function (res) {
      console.log('WebSocket连接已打开!')
      _this.setData({
        isOpenSocket: true
      });
    });

  // 初始化链接

  socket.on("init", function (data) {

    _this.setData({

      client_id: data.client_id

    });

    request({

      url: app.requestUrl('Admin/Match/bind'),

      data: {

        client_id: data.client_id,

        room: 1, // 分组1

      },

      success: res => {

        console.log(res, '用户绑定成功!');

      }

    })

  })

 

6. gateway端操作

<?php
use \GatewayWorker\Lib\Gateway;
use \Workerman\Lib\Timer;
class Events
{
    public static $worker_id = null;
    /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     * 
     * @param int $client_id 连接id
     */
    public static function onConnect($client_id) {
        // 向当前client_id发送数据(触发客户端的init时间)
        Gateway::sendToClient($client_id, json_encode(["init",["client_id"=>$client_id]]));
    }
}

 

7. tp端操作  

  Gateway::$registerAddress = '172.31.239.230:1238';

  class MatchController extends AdminController {

private function bind_user($room,$client_id,$uid=''){
        if( empty($uid) ){
            $sk = $this->checksession();
            $openid = $this->get_openid($sk);
            $uid = D('User')->where(['openid'=>$openid])->getField('id');
        }

        // client_id与uid绑定
        Gateway::bindUid($client_id, $uid);
        // 加入某个群组(可调用多次加入多个群组)
        Gateway::joinGroup($client_id, $room);
     // 设置session
        Gateway::setSession($client_id, ['uid'=>$uid]);
     // 获取客户端分组人数
        $number = Gateway::getClientCountByGroup($room);
        D('Match')->where(['rid'=>$room,'uid'=>$uid,'status'=>['in',['1','2']]])->save(['client_id'=>$client_id]);
        $message = D('Match')->where(['rid'=>$room,'status'=>['in',['1','2']]])->select();
        foreach($message as &$v){
            $v['user'] = D('User')->where(['id'=>$v['uid']])->find();
            $v['user']['teamside'] = D('Match')->where(['rid'=>$room,'uid'=>$v['uid'],'status'=>['in',['1','2']]])->getField('teamside');
        }
     // 向某个房间广播数据
        Gateway::sendToGroup($room, json_encode(["room",$message]));
    }
 }