easyswoole build message queue service 03-basic plug-in configuration
After getting the environment, I started the process of writing code. The environment I used was easyswoole 3.x, and the official chat room Demo was given to me by the official boss. This started the journey of architecture writing. Write, architecture first, the following figure is the architecture sketch I designed, for reference only:
The first problem encountered was the end-to-end encryption problem. I thought of a plug-in called Jwt, which solves the interaction between Api and end (Pc/Android/Ios). It is a very good encryption method, and it is also very useful. simple.
The traditional approach is to store the authenticated user information on the server, such as Session. The user brings the Session ID with the next request, and the server checks whether the user has been authenticated. The advantage of Jwt is to leave the encryption on the client to reduce the pressure on the server.
Install jwt (JSON Web Token)
Install jwt
You can install the official version
composer require lcobucci/jwt
You can also install the easyswoole version
composer require easyswoole/jwt
There is no difference in use, the official GitHub document: https://github.com/huizhang-Easyswoole/jwt, introduced before the class is useduse EasySwoole\Jwt\Jwt;
encryption
/**
* 为用户设置 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;
}
Decrypt 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 and connection pool
The second problem is the way to connect to the data. The official support is Mysqli, Orm, and Elasticsearch. For performance and functionality, I choose Orm and use the connection pool connection method.
Here is a brief talk about the knowledge points of connection pool. As the name implies, connection pool is a conventional means to improve performance and reduce server memory. It specifies the maximum number of connections and minimum number of connections to achieve resource reuse, faster system response speed, and unified connections. Management to avoid the role of database connection leakage.
Mysql-Orm installation
composer require easyswoole/orm
Initialize the load configuration, load Orm, here to say, load the configuration file also needs to be loaded in the initialization initialize
method, do not use the PHP constructor, it may cause bugs.
The root directory EasySwooleEvent.php
of the initialize
method, first load a custom profile:
/**
* 加载自定义配置文件
*/
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);
}
}
If you don’t find the File
class, you use EasySwoole\Utility\File;
need to introduce it at the beginning , you need to pay attention to it yourself, because the version will be different, you need to debug it yourself.
Initially load the Orm component, which GlobalConfig
isuse 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));
File extension of Model layer
namespace App\Models;
use EasySwoole\ORM\AbstractModel;
/**
* 用户Model模型
* Class UserShop
*/
class UserModel extends AbstractModel
{
protected $tableName = 'wm_user_user';
}
Controller call
$userModel = UserModel::create()->field(['user_id'])->get($user_id);
$userData = $userModel->getOriginData();
Redis plugin installation
Install and download the corresponding dependencies by connection pool connection
composer require easyswoole/redis-pool
composer require easyswoole/pool
mainServerCreate
Register the Redis service in the method (called up before the service starts)
//注册 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');
Added redisPool manager, new file/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 call
/**
* @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');
}
Start easyswoole
php easyswoole server start -mode=websocket
Code text is not easy, so encourage