1 开发需要环境
工欲善其事,必先利其器。在正式开发之前我们检查好需要安装的拓展,不要开发中发现这些问题,打断思路影响我们的开发效率。
- 安装 swoole 拓展包
- 安装 redis 拓展包
- 安装 laravel5.5 版本以上
如果你还不会用swoole就out了
程序猿的生活:Laravel 中使用 swoole 项目实战开发案例二 (后端主动分场景给界面推送消息)lifezhuanlan.zhihu.com我的官方群点击此处。获取更多的swoole学习资料以及视频源码笔记。
2 Laravel 生成命令行
- php artisan make:command SwooleDemo
class SwooleDemo extends Command
{protected $signature = 'swoole:demo';protected $description = '这是关于swoole的一个测试demo';public function __construct()
{parent::__construct();
}public function handle()
{$this->line("hello world");
}
}
我们分别运行 php artisan 指令和 php artisan swoole:demo 会看到关于这个命令的说明,和输出 hello world。(laravel 命令行用法详解)
3 命令行逻辑代码
- 编写一个最基础的 swoole 命令行逻辑代码
<?phpnamespace AppConsoleCommands;use IlluminateConsoleCommand;
use IlluminateSupportFacadesRedis;class SwooleDemo extends Command
{// 命令名称protected $signature = 'swoole:demo';// 命令说明protected $description = '这是关于swoole websocket的一个测试demo';// swoole websocket服务private static $server = null;public function __construct(){parent::__construct();}// 入口public function handle(){$this->redis = Redis::connection('websocket');$server = self::getWebSocketServer();$server->on('open',[$this,'onOpen']);$server->on('message', [$this, 'onMessage']);$server->on('close', [$this, 'onClose']);$server->on('request', [$this, 'onRequest']);$this->line("swoole服务启动成功 ...");$server->start();}// 获取服务public static function getWebSocketServer(){if (!(self::$server instanceof swoole_websocket_server)) {self::setWebSocketServer();}return self::$server;}// 服务处始设置protected static function setWebSocketServer():void{self::$server = new swoole_websocket_server("0.0.0.0", 9502);self::$server->set(['worker_num' => 1,'heartbeat_check_interval' => 60, // 60秒检测一次'heartbeat_idle_time' => 121, // 121秒没活动的]);}// 打开swoole websocket服务回调代码public function onOpen($server, $request){if ($this->checkAccess($server, $request)) {self::$server->push($request->fd,"打开swoole服务成功!");}}// 给swoole websocket 发送消息回调代码public function onMessage($server, $frame){}// http请求swoole websocket 回调代码public function onRequest($request,$response){}// websocket 关闭回调代码public function onClose($serv,$fd){$this->line("客户端 {$fd} 关闭");}// 校验客户端连接的合法性,无效的连接不允许连接public function checkAccess($server, $request):bool{$bRes = true;if (!isset($request->get) || !isset($request->get['token'])) {self::$server->close($request->fd);$this->line("接口验证字段不全");$bRes = false;} else if ($request->get['token'] !== "123456") {$this->line("接口验证错误");$bRes = false;}return $bRes;}// 启动websocket服务public function start(){self::$server->start();}}
编写 websoket js 代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>swoole测试</title><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
</head>
<body>
<h1>这是一个测试</h1>
</body>
<script>var ws;//websocket实例var lockReconnect = false;//避免重复连接var wsUrl = 'ws://{{$_SERVER["HTTP_HOST"]}}:9502?page=home&token=123456';function initEventHandle() {ws.onclose = function () {reconnect(wsUrl);};ws.onerror = function () {reconnect(wsUrl);};ws.onopen = function () {//心跳检测重置heartCheck.reset().start();};ws.onmessage = function (event) {//如果获取到消息,心跳检测重置//拿到任何消息都说明当前连接是正常的var data = JSON.parse(event.data);heartCheck.reset().start();}}createWebSocket(wsUrl);/*** 创建链接* @param url*/function createWebSocket(url) {try {ws = new WebSocket(url);initEventHandle();} catch (e) {reconnect(url);}}function reconnect(url) {if(lockReconnect) return;lockReconnect = true;//没连接上会一直重连,设置延迟避免请求过多setTimeout(function () {createWebSocket(url);lockReconnect = false;}, 2000);}//心跳检测var heartCheck = {timeout: 60000,//60秒timeoutObj: null,serverTimeoutObj: null,reset: function(){clearTimeout(this.timeoutObj);clearTimeout(this.serverTimeoutObj);return this;},start: function(){var self = this;this.timeoutObj = setTimeout(function(){//这里发送一个心跳,后端收到后,返回一个心跳消息,//onmessage拿到返回的心跳就说明连接正常ws.send("heartbeat");self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了ws.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次}, self.timeout);}, this.timeout);},header:function(url) {window.location.href=url}}
</script>
</html>
- 访问前端页面 (显示如下说明前后端链接成功)
希望以上内容能帮助到大家,加入我的官方群点击此处。获取更多的swoole学习资料以及视频源码笔记。