easyswoole 搭建消息队列服务03 - 基础插件配置
在搞定环境以后,开始了编写代码的过程,我使用的环境是 easyswoole 3.x,官方大佬给我的聊天室Demo,这就开始了架构编写之旅,兵马未动粮草先行,编码为写,架构先行,下图是我设计的架构草图,仅供参考:
遇到的第一个问题是端与端的加密问题,让我想到了一个叫Jwt的插件,解决Api、端的交互(Pc/Android/Ios),是一种非常好的加密方式,它使用也非常简单。
传统的做法是将已经认证过的用户信息存储在服务器上,比如Session。用户下次请求的时候带着Session ID,然后服务器以此检查用户是否认证过而Jwt的好处在于把加密留在客户端以减少服务端的压力。
安装jwt (JSON Web Token)
安装jwt
可以安装官方版
composer require lcobucci/jwt
也可以安装easyswoole版
composer require easyswoole/jwt
使用上没有什么不同,GitHub官方文档: https://github.com/huizhang-Easyswoole/jwt,在类使用前引入use EasySwoole\Jwt\Jwt;
加密
/**
* 为用户设置 token Jwt
* https://github.com/lcobucci/jwt/blob/3.3/README.md
*/
protected function setToken(){
$jwtObject = Jwt::getInstance()
->setSecretKey('easyswoole') // 秘钥
->publish();
$jwtObject->setAlg('HMACSHA256'); // 加密方式
$jwtObject->setAud('user'); // 用户
$jwtObject->setExp(time()+3600); // 过期时间
$jwtObject->setIat(time()); // 发布时间
$jwtObject->setIss('easyswoole'); // 发行人
$jwtObject->setJti(md5(time())); // jwt id 用于标识该jwt
$jwtObject->setNbf(time()+60*5); // 在此之前不可用
$jwtObject->setSub('主题'); // 主题
// 自定义数据
$jwtObject->setData([
'other_info'
]);
// 最终生成的token
$token = $jwtObject->__toString();
return $token;
}
解密 token
/**
* 获取token的公共接口 Jwt
*/
protected function getToken(){
$auth_token = $this->request()->getHeader('auth_token');
if( empty($auth_token) ){
//密码不正确
}
$jwtObject = Jwt::getInstance()->setSecretKey('easyswoole')->decode($auth_token);
$status = $jwtObject->getStatus();
switch ($status)
{
case -1:
echo 'token无效';
break;
case 1:
echo '验证通过';
....
break;
case 2:
echo '验证失败';
break;
case 3:
echo 'token过期';
break;
}
}
DB与连接池
第二个问题是连接数据的方式,官方支持Mysqli、Orm、和Elasticsearch,出于性能和功能我选择Orm,使用连接池的连接方式。
这里简单的说说连接池的知识点,顾名思义,连接池是提高性能,减小服务器内存的常规手段,规定最大连接数和最小连接数,达到资源重用、更快的系统响应速度、统一的连接管理,避免数据库连接泄露的作用。
Mysql-Orm 安装
composer require easyswoole/orm
初始化加载配置,加载Orm,这里说一下,加载配置文件也需要在初始化的initialize
,方法里加载,不要使用PHP的构造函数,有可能会造成Bug。
根目录EasySwooleEvent.php
的initialize
方法,首先加载自定义配置文件:
/**
* 加载自定义配置文件
*/
public static function loadConf()
{
$ConfPath = EASYSWOOLE_ROOT . '/App/Conf';
$Conf = Config::getInstance();
$files = File::scanDirectory($ConfPath);
if (!is_array($files['files'])) {
return;
}
foreach ($files['files'] as $file) {
echo $file.PHP_EOL;
$data = require_once $file;
$Conf->setConf(strtolower(basename($file, '.php')), (array)$data);
}
}
如果没有找到File
类,开头引入 use EasySwoole\Utility\File;
,需要自己注意一下,因为版本的不同会有所差异,需要同学们自己进行调试。
初始化加载Orm组件,GlobalConfig
就是use EasySwoole\EasySwoole\Config
$dbConf = GlobalConfig::getInstance()->getConf('db');
$config = new DBConfig();
$config->setDatabase($dbConf['mysql-master']['database']);
$config->setUser($dbConf['mysql-master']['username']);
$config->setPassword($dbConf['mysql-master']['password']);
$config->setHost($dbConf['mysql-master']['host']);
$config->setPort($dbConf['mysql-master']['port']);
$config->getCharset($dbConf['mysql-master']['charset']);
//Mysql连接池配置
$config->setGetObjectTimeout(3.0); //设置获取连接池对象超时时间
$config->setIntervalCheckTime(30*1000); //设置检测连接存活执行回收和创建的周期
$config->setMaxIdleTime(15); //连接池对象最大闲置时间(秒)
$config->setMaxObjectNum(20); //设置最大连接池存在连接对象数量
$config->setMinObjectNum(5); //设置最小连接池存在连接对象数量
$config->setAutoPing(5); //设置自动ping客户端链接的间隔
DbManager::getInstance()->addConnection(new Connection($config));
Model层的文件扩展
namespace App\Models;
use EasySwoole\ORM\AbstractModel;
/**
* 用户Model模型
* Class UserShop
*/
class UserModel extends AbstractModel
{
protected $tableName = 'wm_user_user';
}
Controller的调用
$userModel = UserModel::create()->field(['user_id'])->get($user_id);
$userData = $userModel->getOriginData();
Redis插件安装
以连接池连接方式安装下载对应的依赖
composer require easyswoole/redis-pool
composer require easyswoole/pool
mainServerCreate
方法中注册Redis服务(在服务启动前被调起)
//注册 redis连接池
$RedisConfig = new RedisConfig();
$masterRedisConfig = new \EasySwoole\Redis\Config\RedisConfig(GlobalConfig::getInstance()->getConf('redis'));
//注册连接池管理对象
\EasySwoole\Pool\Manager::getInstance()->register(new \App\Pool\RedisPool($RedisConfig,$masterRedisConfig),'redis');
新增redisPool管理器,新增文件/App/Pool/RedisPool.php
namespace App\Pool;
use EasySwoole\Pool\Config;
use EasySwoole\Pool\AbstractPool;
use EasySwoole\Redis\Config\RedisConfig;
use EasySwoole\Redis\Redis;
class RedisPool extends AbstractPool
{
protected $redisConfig;
/**
* 重写构造函数,为了传入redis配置
* RedisPool constructor.
* @param Config $conf
* @param RedisConfig $redisConfig
* @throws \EasySwoole\Pool\Exception\Exception
*/
public function __construct(Config $conf,RedisConfig $redisConfig)
{
parent::__construct($conf);
$this->redisConfig = $redisConfig;
}
protected function createObject()
{
//根据传入的redis配置进行new 一个redis
$redis = new Redis($this->redisConfig);
return $redis;
}
}
Contrllor 调用
/**
* @throws 缓存token
*/
protected function cacheToken($token){
$redis=\EasySwoole\Pool\Manager::getInstance()->get('redis')->getObj();
$redis->select(1);
$result = $redis->set('auth_token:100', $token,['NX','PX'=>20000]);
echo $redis->get('auth_token:100');
}
启动 easyswoole
php easyswoole server start -mode=websocket
码文不易,多多鼓励