easyswoole-使用技巧

easyswoole-使用技巧

使用demo
	https://github.com/easy-swoole/demo/tree/master


1、以借口形式返回json
	$this->writeJson()

2、重写以下方法可实现登录控制,权限控制等
	function onRequest($action):?bool
	{
	    $this->response()->write('no auth');
	    return false;
	}

3、启动时设置端口
	php easyswoole start --p-4000

4、EASYSWOOLE_ROOT 项目根目录

创建一个BaseController
	namespace App\HttpController\Api;
	use EasySwoole\Core\Http\AbstractInterface\Controller;
	class Base extends Controller
	{
		// 必须要实现的方法
	    public function index()
	    {
	        
	    }

	    // 进入action之前的校验阶段
	    public function onRequest($action):?bool
	    {
	        return true;
	    }

	    // 不想在所有的action里都加try...catch的话,可以在这里统一抛出
	    // 即,如果action里有异常,就会自动回调到这个函数,参见 __hoke()函数
	    public function onException(\Throwable $throwable,$actionName):void
	    {
	    	// 情况输出缓冲区的数据,防止action中其他的输出被输出,只能清除action中的
	    	$this->response()->getBody()->truncate();
	    	// 一旦有异常就做以下输出
	        $this->writeJson(400, null, '系统错误');
	    }

	    // action执行完毕后,会走到这里
	    public function afterAction($actionName): void
	    {

	    }
	}

数据库
	easyswoole本身没有实现数据库的连接
	参考:http://easyswoole.com/Manual/2.x/Cn/_book/Database/mysqli_db.html
	具体使用:https://github.com/ThingEngineer/PHP-MySQLi-Database-Class

	composer require joshcam/mysqli-database-class:dev-master
	在vendor/joshcam

	确认已安装mysqli扩展

	在框架的\EasySwoole\EasySwooleEvent::mainServerCreate中,引入了MysqliDb.php后,即可进行IOC注入。
	use \EasySwoole\Core\Component\Di;
	use \App\Lib\RedisClient;
	public static function mainServerCreate(ServerManager $server,EventRegister $register): void
    {
        Di::getInstance()->set('MYSQL',\MysqliDb::class, \Yaconf::get('database'));
        Di::getInstance()->set('REDIS',RedisClient::class, \Yaconf::get('redis'));
    }

	使用:
	use \EasySwoole\Core\Component\Di;
	function video()
    {
        $db = Di::getInstance()->get('MYSQL');
        $re = $db->where('id', 1)->getOne('video');
        return $this->writeJson(200, 'ok', $re);
    }

    使用了yaconf之后,port变量会变化字符串,需要将 MysqliDb.php: 280行改成 'port' => (int)$port,

php7特性 
	1、trait
		将类作为代码块引入
		EasySwoole\Core\AbstractInterface\Singleton.php文件

		namespace EasySwoole\Core\AbstractInterface;

		trait Singleton
		{
		    private static $instance;

		    static function getInstance(...$args)
		    {
		        if(!isset(self::$instance)){
		            self::$instance = new static(...$args);
		        }
		        return self::$instance;
		    }
		}

		在需要用到的地方
		引入
			use EasySwoole\Core\AbstractInterface\Singleton;
		使用
			class Di
			{
			    use Singleton;
			    private $container = array();
			}

	2、获取类名(包括命名空间)
		use \App\Lib\RedisClient;
		var_dump(RedisClient::class);// App\Lib\RedisClient
		当需要传递类名用在其他地方实例化时,可以这样:
		例如:Di::getInstance()->set('REDIS', RedisClient::class, \Yaconf::get('redis'));

	3、三元运算符和isset()的简化
		$a ?? 'a' 等价于 $a ? $a : 'a';
		isset($_GET[‘id']) ? $_GET[id] : 'err'; 等价于 $_GET['id'] ?? 'err';

	4、限制函数的返回类型
		function test(): array
		{

		}

		function test(): void
		{

		}
	5、匿名类
		new class implements Logger

	6、函数参数类型的限制
		string, int, bool, float, array, classname, 

	7、批量引入命名空间
		use some\namespace\{ClassA, ClassB, ClassC as C};

	8、三点号语法
		从第二个参数开始,后面的参数将被注入到一个数组中
		function test($param1, ...$args){
			var_dump($args);
		}

		test(1, 2, 3, 4);

	9、php反射类
		\ReflectionClass
		\ReflectionMethod

		用于类的实例化,及其他功能

		参考另一篇文章


自定义进程
	介绍
	http://easyswoole.com/Manual/2.x/Cn/_book/Advanced/process.html
	自定义进程的实现
	http://easyswoole.com/Manual/2.x/Cn/_book/Other/process.html

前后端分离
	node.js
	vue
	
	npm install 依赖安装 
	npm run dev  编译,并启动node服务器作为web服务

	上线部署
	npm run build  压缩项目,这个命令可在本地执行,然后将dist下面的index.html和static/文件夹复制到线上即可

nginx设置转发
	编译安装nginx到指定位置
	./configure --prifix=/usr/local/nginx1.15
	如果要在一个服务器安装多个不同版本相同的软件,需要编译安装,因为这样就可以指定安装目录了。

	在任何一个location里面
	if (!-e $request_file) {
		proxy_pass http://127.0.0.1:8000
	}
	表示,如果当前server无法响应某个请求,就将该请求转发到 http://127.0.0.1:8000
	可以转发到某个服务器的某个端口
	注意 if后面要紧跟一个空格

点播
	点播,已录制好的视频
	小视频,3-5分钟
	视频上传--存储--转码--分发--加速播放
	一般会将视频转码为m3u8格式
	一般上传到第三方平台(腾讯云,阿里云,七牛云)提供的视频点播服务
	先将视频上传到自己的服务器,然后使用异步的方式来传到第三方平台

	如果自己做视频服务器的话,需要单独整一台服务器4用来存储,服务器1,2,3上的用户上传的视频需要一步转移到
	服务器4上,linux下scp命令来做。

文件上传
	$data  = $this->request()->getUploadedFile('name');
	$all = $this->request()->getUploadFiles();

	$data为文件对象
	$re = $data->moveTo('./upload/1.mp4');

	生成唯一key
	Utils::getFileKey()

	文件后缀名
	$info = pathinfo($filename);
	$ext = $info['extension'];

	使用反射类
	
获取请求ip
	在控制器里面
	$ipObj = ServerManager::getInstance()->getServer()->connection_info($this->request()->getSwooleRequest()->fd);
    echo $ipObj['remote_ip'];

状态码类
	Status::

数据校验类
	new Rules();

	Rule::

	(new Validate)->validate($data, $rules);

	它会全部校验,然后返回一个包含多个错误的数组,获取第一个错误就可以了

关于 try,catch,throw



阿里云点播服务的体验版的实践
	下载php-sdk,放到项目中
	按照官方文档实现

	需要分分两步实现

	1、获取视频上传地址和凭证
		相当于先占好了一个位置
	2、将文件传递到1返回的位置上去
		用户通过表单上传文件后会有一个临时文件,直接将临时文件作为参数就可以了。

	格式化时长

分类菜单写入缓存

数据定时缓存
	添加定时任务,系统启动时就会注册执行,定时生成缓存
		easyswoole+crontab,最小颗粒为分  
			类:Component/Crontab/CronTab.php,
			使用:EasySwooleEvent.php    
				mainServerCreate
				CronTab::getInstance()->addRule()

		easyswoole+Timer,最小颗粒毫秒,必须在服务启动之后使用
			EasySwoole\Core\Swoole\Time\Timer.php
			使用:EasySwooleEvent.php    
				mainServerCreate
				需要注册一个进程启动事件来执行定时器
				$register->add(EventRegister::onWorkerStart, function(\swoole_server $server, $workerId) use ($cacheDataObj){
					// 此处选择进程1来执行定时器
					// 注意use需要一级一级往下传递变量
					if($workerId == 0){
						Timer::loop(1000, function() use ($cacheDataObj){
							var_dump(1);// 写生成缓存的逻辑
						})
					}
				})

	将最新的1000条记录定时写入缓存
		1、文件缓存  json file

		2、内存缓存  可以存数组或其他数据类型
			文档:https://wiki.swoole.com/wiki/page/p-table.html
			实现的超高性能,并发数据结构
			每秒可读写200万次
			easyswoole对swoole的table做的封装 EasySwoole\Core\Component\Cache\Cache

			use EasySwoole\Core\Component\Cache\Cache
			Cache::getInstance()->set('index', $data);
			Cache::getInstance()->get('index');

			使内存的缓存在重启服务时不丢失,需要设置Config.php中的PERSISTENT_TIME定时备份间隔,默认0不备份
				'EASY_CACHE'=>[
			        'PROCESS_NUM'=>1,//若不希望开启,则设置为0
			        'PERSISTENT_TIME'=>1//如果需要定时数据落地,请设置对应的时间周期,单位为秒
			    ],
			    备份的数据在Temp目录下

		3、redis缓存

		使用适配器模式

		分页读出缓存:全部读出来,array_splice切片
				
	
关于闭包
	回调函数就是一个闭包,闭包顾名思义就是一个封闭的单元,外部变量无法在里面直接使用,需要使用use关键字
	function() use ($a, $b) {
		var_dump($a);
		var_dump($b);
	}

instanceof
	判断一个对象是否是一个类的实例
	if($logger instanceof LoggerWriterInterface){
        $this->loggerWriter = $logger;
    }


修改后自动热重启
	安装inotify扩展
	定义进程:
		https://github.com/easy-swoole/demo/blob/master/EasySwooleEvent.php
		https://github.com/easy-swoole/demo/blob/master/Application/Process/Inotify.php

	测试通过


nginx+lua
	openresty工具

php easyswoole stop --f 强制关闭服务

点赞排名的实现
	点赞使用异步方式更新到redis
	task异步任务
		文档:https://wiki.swoole.com/wiki/page/134.html
		投递一个异步任务到task_worker进程
		Config.php
			task_worker_num  异步任务进程

		使用
		use EasySwoole\Core\Swoole\Task\TaskManager
		TaskManager::async(function(){

		})

	redis中的有序集合zset
		ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment
		ZREVRANGE key start stop [WITHSCORES] 返回有序集中指定区间内的成员,通过索引,分数从高到底,即关联数组

		实际应用中可以为每天定义一个key,比如 star_2019_3_12

		那么对于周排行,月排行,可以使用函数
		ZUNIONSTORE destination numkeys key [key ...] 计算给定的一个或多个有序集的并集,并存储在新的 key 中。
		需要实时的话可以使用定时器来定时生成。


elasticsearch
	由java开发的开源软件
	https://www.elastic.co/

	实时搜索,快速,稳定,实时计算

	1、java -version
	java版本>=1.8

	2、下载elasticsearch
	https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.6.1.tar.gz
	https://www.elastic.co/downloads/elasticsearch
	解压到一个目录下
	配置
		1、配置Linux系统
			https://github.com/elastic/elasticsearch/issues/22245

		2、配置elasticsearch
			./config/elasticsearch.yml
				注意:冒号后面有个空格
				xpack.ml.enabled: false
				network.host: 0.0.0.0
				http.port: 8301
				#memory
				bootstrap.memory_lock: false
				bootstrap.system_call_filter: false
				#允许跨域请求,允许head插件访问
				http.cors.enabled: true
				http.cors.allow-origin: "*"
	启动
		./bin/elasticsearch
		./bin/elasticsearch -d 以守护进程启动
		启动需要一点时间

		访问接口
		192.168.10.20:8301

	head插件
	elasticsearch集群配置
	elasticsearch-php扩展类库

你可能感兴趣的:(swoole)