美文网首页
[折腾]-thinkphp与workerman整合后wss协议问

[折腾]-thinkphp与workerman整合后wss协议问

作者: soar1997 | 来源:发表于2018-04-24 15:23 被阅读0次

    在博主的努力下,博主自己从零搭建的博客网站已经上线了,这篇文章已经转移到了博主自己的博客网站上了,欢迎访问
    thinkphp与workerman整合后wss协议问题

    这似乎是个简单的问题,最新版本的tp5已经整合了workerman,手册里也给出了ws://协议下的demo,但是需要wss://该怎么办?

    尽管workerman的手册建议我们把workerman模块独立出来,但是按照tp5手册,安装workerman扩展只需要composer安装,而且安装后看起来这个扩展不是原汁原味的workerman的使用方法而是直接遵照tp5的开发规范。

    tp5手册给出的安装方法:

    composer require topthink/think-worker
    

    tp5手册给出的demo:

    新增启动服务文件server.php,在项目根目录

    #!/usr/bin/env php
    <?php
    define('APP_PATH', __DIR__ . '/application/');
    define('BIND_MODULE','push/Worker');
    // 加载框架引导文件
    require __DIR__ . '/thinkphp/start.php';
    

    新增服务处理类,push.app是我本地测试域名

    <?php
    
    namespace app\push\controller;
    
    use think\worker\Server;
    
    class Worker extends Server
    {
        protected $socket = 'websocket://push.app:2346';
    
        /**
         * 收到信息
         * @param $connection
         * @param $data
         */
        public function onMessage($connection, $data)
        {
            $connection->send('我收到你的信息了');
        }
    
        /**
         * 当连接建立时触发的回调函数
         * @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)
        {
    
        }
    }
    

    在命令行下运行,启动监听服务

    php server.php start
    

    workerman3.x手册给出的wss://demo

    看起来更方便的方法一

    <?php
    require_once __DIR__ . '/Workerman/Autoloader.php';
    use Workerman\Worker;
    
    // 证书最好是申请的证书
    $context = array(
        // 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
        'ssl' => array(
            // 请使用绝对路径
            'local_cert'                 => '磁盘路径/server.pem', // 也可以是crt文件
            'local_pk'                   => '磁盘路径/server.key',
            'verify_peer'                => false,
            // 'allow_self_signed' => true, //如果是自签名证书需要开启此选项
        )
    );
    // 这里设置的是websocket协议(端口任意,但是需要保证没被其它程序占用)
    $worker = new Worker('websocket://0.0.0.0:443', $context);
    // 设置transport开启ssl,websocket+ssl即wss
    $worker->transport = 'ssl';
    $worker->onMessage = function($con, $msg) {
        $con->send('ok');
    };
    
    Worker::runAll();
    

    矛盾

    workerman3.x给出的demo设置了$context选项,在对象初始化的时候传递给了构造函数
    __construct($socket_name, $context_option)
    但是tp5手册似乎完全没有给出如何传递$context的传递方法,这对我这样的麻瓜PHPer来说就很蛋疼,搜索又搜不到解决办法,只有生气才能……

    解决

    克服心理障碍,勇敢地提出魔改的想法,因此我仔细看了看tp5项目目录下的vender目录,发现:

    tp5手册给出的ws://demo中创建的Worker类继承了Server类,这个类位于vender/topthink/think-worker/src/Server.php

    打开这个文件,一切都明了了,这个Server类无非是对workerman的再次封装,这个类里面的“操作”就和workerman3.x手册给出的“操作”很像了。

    vender/workerman目录下是workerman的庐山真面目,Server.php中也是引用了其中的Worker类。

    魔改

    Server.php

    ...
    abstract class Server{
        ...
        protected $socket;
        protected $context;
        ...
        public function __construct(){
            // 实例化 Websocket 服务
            $this->worker = new Worker($this->socket, $this->context);
            ...
        }
        ...
    }
    ...
    

    application/project/controller/Worker.php

    <?php
    namespace app\project\controller;
    
    use think\worker\Server;
    use Workerman\Lib\Timer;
    ...
    class Worker extends Server{
        protected $socket = 'websocket://0.0.0.0:4431';
        protected $context = [
            'ssl' => [
            'local_cert' => '磁盘路径/server.pem',
            'local_pk' => '磁盘路径/server.key',
            'verify_peer' => false,
            ],
        ];
        protected $transport = 'ssl';
        
        public function onConnect($conn){
            ...
        }
        ...
    }
    ...
    ?>
    

    相关文章

      网友评论

          本文标题:[折腾]-thinkphp与workerman整合后wss协议问

          本文链接:https://www.haomeiwen.com/subject/zqsjlftx.html