thinkphp5+GatewayWorker+Workerman+多协议支持

Windows版安装

  1. 安装thinkphp5;
    composer create-project topthink/think tp5 --prefer-dist

  2. 进入tp5的目录,安装Windows版本的workerman;
    composer require workerman/workerman-for-win

  3. 安装Windows版本的gateway;
    composer require workerman/gateway-worker-for-win

服务端实现

控制器:app\push\controller\Sregister

<?php


namespace app\push\controller;
use \Workerman\Worker;
use \GatewayWorker\Register;

class Sregister
{
    public function __construct()
    {
        // register 必须是text协议
        $register = new Register('text://0.0.0.0:1236');

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

}

控制器:app\puah\controller\Sgateway

<?php


namespace app\push\controller;

use \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
use \Workerman\Autoloader;

class Sgateway
{

    public function __construct()
    {
        // gateway 进程,这里使用Text协议,可以用telnet测试
        $gateway = new Gateway("Text://0.0.0.0:8013");
        // gateway名称,status方便查看
        $gateway->name = 'shareac';
        // gateway进程数
        $gateway->count = 4;
        // 本机ip,分布式部署时使用内网ip
        $gateway->lanIp = '127.0.0.1';
        // 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
        // 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
        $gateway->startPort = 2900;
        // 服务注册地址
        $gateway->registerAddress = '127.0.0.1:1236';

        // 心跳间隔
        $gateway->pingInterval = 55;

        $gateway->pingNotResponseLimit = 3;
        // 心跳数据
//        $gateway->pingData = '{"type":"ping"}';

        /*
        // 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调
        $gateway->onConnect = function($connection)
        {
            $connection->onWebSocketConnect = function($connection , $http_header)
            {
                // 可以在这里判断连接来源是否合法,不合法就关掉连接
                // $_SERVER['HTTP_ORIGIN']标识来自哪个站点的页面发起的websocket链接
                if($_SERVER['HTTP_ORIGIN'] != 'http://kedou.workerman.net')
                {
                    $connection->close();
                }
                // onWebSocketConnect 里面$_GET $_SERVER是可用的
                // var_dump($_GET, $_SERVER);
            };
        };
        */

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

    }
}

控制器:app\push\controller\Sbusinessworker

<?php


namespace app\push\controller;
use \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
use \Workerman\Autoloader;

class Sbusinessworker
{
    public function __construct()
    {
        // bussinessWorker 进程
        $worker = new BusinessWorker();
        // worker名称
        $worker->name = 'shareacWorker';
        // bussinessWorker进程数量
        $worker->count = 4;
        // 服务注册地址
        $worker->registerAddress = '127.0.0.1:1236';
        $worker->eventHandler = 'app\push\controller\Events';
        // 如果不是在根目录启动,则运行runAll方法
        if (!defined('GLOBAL_START')) {
            Worker::runAll();
        }
    }
}

控制器:app\push\controller\Sgatewaywebsocket

<?php


namespace app\push\controller;

use \Workerman\Worker;
use \Workerman\WebServer;
use \GatewayWorker\Gateway;
use \GatewayWorker\BusinessWorker;
use \Workerman\Autoloader;

class Sgatewaywebsocket
{

    public function __construct()
    {
        // 证书最好是申请的证书

        //$context = array(
        //    // 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
        //    'ssl' => array(
        //        // 请使用绝对路径
        //        'local_cert'                 => '/home/jhq/ssl/smartlife.pem', // 也可以是crt文件
        //        'local_pk'                   => '/home/jhq/ssl/smartlife.key',
        //        'verify_peer'               => false,
        //        // 'allow_self_signed' => true, //如果是自签名证书需要开启此选项
        //    )
        //);

        // gateway 进程,这里使用Text协议,可以用telnet测试
        $gateway = new Gateway("Websocket://0.0.0.0:2346");

        // 开启SSL,websocket+SSL 即wss
        //$gateway->transport = 'ssl';

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

        // 心跳间隔
//        $gateway->pingInterval = 55;

//        $gateway->pingNotResponseLimit = 1;
        // 心跳数据
//        $gateway->pingData = '{"type":"ping"}';

        /*
        // 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调
        $gateway->onConnect = function($connection)
        {
            $connection->onWebSocketConnect = function($connection , $http_header)
            {
                // 可以在这里判断连接来源是否合法,不合法就关掉连接
                // $_SERVER['HTTP_ORIGIN']标识来自哪个站点的页面发起的websocket链接
                if($_SERVER['HTTP_ORIGIN'] != 'http://kedou.workerman.net')
                {
                    $connection->close();
                }
                // onWebSocketConnect 里面$_GET $_SERVER是可用的
                // var_dump($_GET, $_SERVER);
            };
        };
        */

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

    }
}

控制器:app\push\controller\Events

<?php

namespace app\push\controller;

use app\common\controller\Worker;
use GatewayWorker\Lib\Gateway;

class Events
{
    /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     *
     * @param int $client_id 连接id
     */
    public static function onConnect($client_id)
    {

    }

    /**
     * 当客户端发来消息时触发
     * @param int $client_id 连接id
     * @param mixed $message 具体消息
     */
    public static function onMessage($client_id, $message)
    {
        $message = json_decode($message, 1);
        /*业务逻辑控制器*/
        $con = new Worker();

        switch ($message['Type']) {
            case 'reg':
                //接收登录包
                $verify = $con->verify($message['Key'], $message['Imei']);
                if (!$verify) {
                    return Gateway::closeClient($client_id); //验证失败,断开连接
                }
                $_SESSION['uid'] = $message['Imei'];
                Gateway::bindUid($client_id, $message['Imei']);
                $data['Type'] = 'reg';
                $data['Time'] = time();
                $sendData = '0' . json_encode($data);
                Gateway::sendToClient($client_id, $sendData);
                $con->saveHeart($_SESSION['uid'], $message, 'reg'); //存心跳状态
                break;
            case 'heartbeat':
                //接收心跳包
                if (!isset($_SESSION['uid'])) {
                    return Gateway::closeClient($client_id); //设备未登录,断开连接
                }
                $data['Type'] = 'reply';
                $data['Time'] = time();
                $sendData = '0' . json_encode($data);
                Gateway::sendToClient($client_id, $sendData);
                $con->saveHeart($_SESSION['uid'], $message, 'heartbeat'); //更新心跳包数据
                break;


                /*其他接收类型按需求补充……*/

        }
    }

    /**
     * 当用户断开连接时触发
     * @param int $client_id 连接id
     */
    public static function onClose($client_id)
    {
        $con = new Worker();
        //设备心跳断开
        if ($_SESSION['uid'] && !Gateway::isUidOnline($_SESSION['uid'])) {
            $con->offline($_SESSION['uid']);
        }
    }
}

在项目根目录 新增入口文件 start_register.php 、start_gateway.php 、start_businessworker.php、start_gateway_websocket.php四个入口文件

文件:start_register.php

<?php
define('APP_PATH', __DIR__ . '/../application/');
define('BIND_MODULE','push/Sregister');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';

文件:start_gateway.php

<?php
define('APP_PATH', __DIR__ . '/../application/');
define('BIND_MODULE','push/Sgateway');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';

文件:start_businessworker.php

<?php
define('APP_PATH', __DIR__ . '/../application/');
define('BIND_MODULE','push/Sbusinessworker');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';

文件:start_gateway_websocket.php

<?php
define('APP_PATH', __DIR__ . '/../application/');
define('BIND_MODULE','push/Sgatewaywebsocket');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
  1. 由于PHP-CLI在windows系统无法实现多进程以及守护进程,所以只能把三个文件放到bat文件,然后双击启动
    bat文件:start_for_win.bat
    php start_register.php start_gateway.php start_businessworker.php start_gateway_websocket.php pause

在这里插入图片描述

linux版安装

  1. 安装thinkphp5;
    composer create-project topthink/think tp5 --prefer-dist
  2. 进入tp5的目录,安装linux版本的workerman;
    composer require topthink/think-worker
  3. 安装linux版本的gateway;
    composer require workerman/gateway-worker
  4. 关键部分,服务端实现
    复制代码

控制器 app\push\controller\Gate

<?php

namespace app\push\controller;

use Workerman\Worker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use GatewayWorker\BusinessWorker;


class Gate
{
    /**
     * 构造函数
     * @access public
     */
    public function __construct()
    {

        //初始化各个GatewayWorker
        //初始化register register 服务必须是text协议
        $register = new Register('text://0.0.0.0:1236');

        //初始化 bussinessWorker 进程
        $worker = new BusinessWorker();
        // worker名称
        $worker->name = 'shareacWorker';
        // bussinessWorker进程数量
        $worker->count = 4;
        // 服务注册地址
        $worker->registerAddress = '127.0.0.1:1236';
        //设置处理业务的类,此处制定Events的命名空间
        $worker->eventHandler = 'app\push\controller\Events';

        /*面向硬件*/
        // 初始化 gateway 进程
        $gateway = new Gateway("Text://0.0.0.0:8013");
        // 设置名称,方便status时查看
        $gateway->name = 'shareac';
        $gateway->count = 4;
        // 分布式部署时请设置成内网ip(非127.0.0.1)
        $gateway->lanIp = '127.0.0.1';
        // 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
        // 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
        $gateway->startPort = 2900;
        // 心跳间隔
        $gateway->pingInterval = 55;
        $gateway->pingNotResponseLimit = 3;
        // 心跳数据
//        $gateway->pingData = '{"type":"ping"}';
        // 服务注册地址
        $gateway->registerAddress = '127.0.0.1:1236';

        /*面向小程序*/
        // 证书最好是申请的证书
        $context = array(
            'ssl' => array(
                // 请使用绝对路径
                'local_cert' => '磁盘路径/server.pem', // 也可以是crt文件
                'local_pk' => '磁盘路径/server.key',
                'verify_peer' => false,
                // 'allow_self_signed' => true, //如果是自签名证书需要开启此选项
            )
        );

        $gateway_web = new Gateway("Websocket://0.0.0.0:2346", $context);
        // 开启SSL,websocket+SSL 即wss
        $gateway_web->transport = 'ssl';
        // gateway名称,status方便查看
        $gateway_web->name = 'shareacApp';
        // gateway进程数
        $gateway_web->count = 4;
        // 本机ip,分布式部署时使用内网ip
        $gateway_web->lanIp = '127.0.0.1';
        // 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
        // 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
        $gateway_web->startPort = 3000;
        // 服务注册地址
        $gateway_web->registerAddress = '127.0.0.1:1236';

        //运行所有Worker;
        Worker::runAll();
    }
}

入口文件
文件:start.php

<?php
/**
 * workerman + GatewayWorker
 * 此文件只能在Linux运行
 * run with command
 * php start.php start
 */
ini_set('display_errors', 'on');
if(strpos(strtolower(PHP_OS), 'win') === 0)
{
    exit("start.php not support windows.\n");
}
//检查扩展
if(!extension_loaded('pcntl'))
{
    exit("Please install pcntl extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}
if(!extension_loaded('posix'))
{
    exit("Please install posix extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}

define('APP_PATH', __DIR__ . '/../application/');
define('BIND_MODULE','push/Gate');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';

启动程序
php start.php start

本文借鉴来源:https://blog.csdn.net/niefudong/article/details/96473456

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值