在博主的努力下,博主自己从零搭建的博客网站已经上线了,这篇文章已经转移到了博主自己的博客网站上了,欢迎访问
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){
...
}
...
}
...
?>
网友评论