Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)
程序员文章站
2022-06-10 22:32:00
1 开发需要环境 工欲善其事,必先利其器。在正式开发之前我们检查好需要安装的拓展,不要开发中发现这些问题,打断思路影响我们的开发效率。 安装 swoole 拓展包 安装 redis 拓展包 安装 laravel5.5 版本以上 如果你还不会用swoole就out了 2 Laravel 生成命令行 p ......
1 开发需要环境
工欲善其事,必先利其器。在正式开发之前我们检查好需要安装的拓展,不要开发中发现这些问题,打断思路影响我们的开发效率。
- 安装 swoole 拓展包
- 安装 redis 拓展包
- 安装 laravel5.5 版本以上
如果你还不会用swoole就out了
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 命令行逻辑代码
<?php namespace app\console\commands; use illuminate\console\command; use illuminate\support\facades\redis; 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> 访问前端页面 (显示如下说明前后端链接成功)
上一篇: Java文件流的常见错误
下一篇: 皇帝驾崩太子伤心吗?悲伤都是装的!