推荐阅读:laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)
我们假设有一个需求,我在后端点击按钮 1,首页弹出 “后端触发了按钮 1”。后端点了按钮 2,列表页弹出 “后端触发了按钮 2”。做到根据不同场景推送到不同页面。
127.0.0.1:9502page=back&func=pushhomelogic&token=123456
我们可以根据传入的func参数,在后台分发给对应逻辑处理。如分发给pushhomelogic方法。在其里面实现自己的逻辑。为防止过多的ifel以及foreach 操作,我们采用的是闭包,call_ur_func等方法实现如下1 public function onrequest($request,$respon) 2 { 3 if ($this->checkaccess("", $request)) { 4 $param = $request->get; 5 // 分发处理请求逻辑 6 if (ist($param['func'])) { 7 if (method_exists($this,$param['func'])) { 8 call_ur_func([$this,$param['func']],$request); 9 }10 }11 }12 }// 往首页推送逻辑处理13 public function pushhomelogic($request)14 {15 $callback = function (array $acontent,int $fd,swooledemo $oswoole)u($request) {16 if ($acontent && $acontent['page'] == "home") {17 $ares['message'] = "后端按了按钮1";18 $ares['code'] = "200";19 $oswoole::$rver->push($fd,xss_json($ares));20 }21 };22 $this->eachfdlogic($callback);23 }
swool 脚本代码逻辑
1 <?php 2 3 namespace app\console\commands; 4 5 u closure; 6 u illuminate\console\command; 7 u illuminate\support\facades\redis; 8 9 class swooledemo extends command 10 { 11 // 命令名称 12 protected $signature = 'swoole:demo'; 13 // 命令说明 14 protected $description = '这是关于swoole websocket的一个测试demo'; 15 // swoole websocket服务 16 private static $rver = null; 17 18 public function __construct() 19 { 20 parent::__construct(); 21 } 22 23 // 入口 24 public function handle() 25 { 26 $this->redis = redis::connection('websocket'); 27 $rver = lf::getwebsocketrver(); 28 $rver->on('open',[$this,'onopen']); 29 $rver->on('message', [$this, 'onmessage']); 30 $rver->on('clo', [$this, 'onclo']); 31 $rver->on('request', [$this, 'onrequest']); 32 $this->line("swoole服务启动成功 ..."); 33 $rver->start(); 34 } 35 36 // 获取服务 37 public static function getwebsocketrver() 38 { 39 if (!(lf::$rver instanceof \swoole_websocket_rver)) { 40 lf::twebsocketrver(); 41 } 42 return lf::$rver; 43 } 44 // 服务处始设置 45 protected static function twebsocketrver():void 46 { 47 lf::$rver = new \swoole_websocket_rver("0.0.0.0", 9502); 48 lf::$rver->t([ 49 'worker_num' => 1, 50 'heartbeat_check_interval' => 60, // 60秒检测一次 51 'heartbeat_idle_情人节甜言蜜语time' => 121, // 121秒没活动的 52 ]); 53 } 54 55 // 打开swoole websocket服务回调代码 56 public function onopen($rver, $request) 57 { 58 if ($this->checkaccess($rver, $request)) { 59 lf::$rver->push($request->fd,xss_json(["code"=>200,"message"=>"打开swoole服务成功"])); 60 } 61 } 62 // 给swoole websocket 发送消息回调代码 63 public function onmessage($rver, $frame) 64 { 65 66 } 67 // http请求swoole websocket 回调代码 68 public function onrequest($request,$respon) 69 { 70 if ($this->checkaccess("", $request)) { 71 $param = $request->get; 72 // 分发处理请求逻辑 73 if (ist($param['func'])) { 74 if (method_exists($this,$param['func'])) { 75 call_ur_func([$this,$param['func']],$request); 76 } 77 } 78 } 79 } 80 81 // websocket 关闭回调代码 82 public function onclo($rv,$fd) 83 { 84 $this->redis->hdel('swoole:fds', $fd); 85 $this->line("客户端 {$fd} 关闭"); 86 } 87 88 // 校验客户端连接的合法性,无效的连接不允许连接 89 public function checkaccess($rver, $request):bool 90 { 91 $bres = true; 92 if (!ist($request->get) || !ist($request->get['token'])) { 93 lf::$rver->clo($request->fd); 94 $this->line("接口验证字段不全"); 95 $bres = fal; 96 } el if ($request->get['token'] != 123456) { 97 $this->line("接口验证错误"); 98 $bres = fal; 99 }100 $this->storeurlparamtoredis($request);101 return $bres;102 }103 104 // 将每个界面打开websocket的url 存储起来105 public function storeurlparamtoredis($request):void106 {107 // 存储请求url带的信息108 $scontent = json_encode(109 [110 'page' => $request->get['page'],111 'fd' => $request->fd,112 ], true);113 $this->redis->ht("swoole:fds", $request->fd, $scontent);114 }115 116 /**117 * @param $request118 * @e 循环逻辑处理119 */120 public function eachfdlogic(closure $callback = null)121 {122 foreach (lf::$rver->connections as $fd) {123 if (lf::$rver->istablished($fd)) {124 $acontent = json_decode($this->redis->hget("swoole:fds",$fd),true);125 $callback($acontent,$fd,$this);126 } el {127 $this->redis->hdel("swoole:fds",$fd);128 }129 }130 }131 // 往首页推送逻辑处理132 public function pushhomelogic($request)133 {134 $callback = function (array $acontent,int $fd,swooledemo $oswoole)u($request) {135 if ($acontent && $acontent['page'] == "home") {136 $ares['message'] = "后端按了按钮1";137 $ares['code'] = "200";138 $oswoole::$rver->push($fd,xss_json($ares));139 }140 };141 $this->eachfdlogic($callback);142 }143 // 往列表页推送逻辑处理144 public function pushlistlogic($request)145 {146 $callback = function (array $acontent,int $fd,swooledemo $oswoole)u($request) {147 if ($acontent && $acontent['page'] == "list") {148 $ares['message'] = "后端按了按钮2";149 $ares['code'] = "200";150 $oswoole::$rver->push($fd,xss_json($ares));151 }152 };153 $this->eachfdlogic($callback);154 }155 156 // 启动websocket服务157 public function start()158 {159 lf::$rver->start();160 }161 }162 控制器代码163 164 <?php165 166 namespace app\http\controllers;167 168 u illuminate\http\request;169 u illuminate\support\facades\redis;170 class testcontroller extends controller171 {172 // 首页173 public function home()174 {175 return view江苏新高考("home");176 }177 // 列表178 public function list()179 {180 return view("list");181 }182 // 后端控制183 public function back()184 {185 if (request()->method() == 'post') {186 $this->curl_get($this->geturl());187 return json_encode(['code'=>200,"message"=>"成功"]);188 } el {189 return view("back");190 }191 192 }193 // 获取要请求swoole websocet服务地址194 public function geturl():string195 {196 // 域名 端口 请求swoole服务的方法197 $sba = request()->rver('http_host');198 $iport = 9502;199 $sfunc = request()->post('func');200 $spage = "back";201 return $sba.":".$iport."?func=".$sfunc."&token=123456&page=".$spage;202 }203 // curl 推送204 public function cu北京舞蹈培训rl_get(string $url):string205 {206 $ch_curl = curl_init();207 curl_topt ($ch_curl, curlopt_timeout_ms, 3000);208 curl_topt($ch_curl, curlopt_ssl_verifypeer, 0);209 curl_topt ($ch_curl, curlopt_header,fal);210 curl_topt($ch_curl, curlopt_httpget, 1);211 curl_topt($ch_curl, curlopt_returntransfer,true);212 curl_topt ($ch_curl, curlopt_url,$url);213 $str = curl_exec($ch_curl);214 curl_clo($ch_curl);215 return $str;216 }217 }
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta chart="utf-8"> 5 <title>后端界面</title> 6 <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,ur-scalable=no"> 7 </head> 8 <body> 9 <button class="push" data-func="pushhomelogic">按钮1</button>10 <button class="push" data-func="pushlistlogic">按钮2</button>11 </body>12 <script src="{{ ast("/vendor/tw/global/jquery/jquery-2.2.3.min.js")}} "></script>13 <script>14 $(function () {15 $(".push").on('click',function(){16 var func = $(this).attr('data-func').trim();17 ajaxget(func)18 })19 function ajaxget(func) {20 url = "{{route('back')}}";21 token = "{{csrf_token()}}";22 $.ajax({23 url: url,24 type: 'post',25 datatype: "json",26 data:{func:func,_token:token},27 error: function (data) {28 alert("服务器繁忙, 请联系管理员!");29 return;30 },31 success: function (result) {32 33 },34 })35 }36 37 })38 </script>39 </html>
首页
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta chart="utf-8"> 5 <title>swoole首页</title> 6 <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,ur-scalable=no"> 7 </head> 8 <body> 9 <h1>这是首页</h1>10 </body>11 <script>12 var ws;//websocket实例13 var lockreconnect = fal;//避免重复连接14 var wsurl = 'ws://{{$_rver["http_host"]}}:9502?page=home&token=123456';15 16 function initeventhandle() {17 ws.onclo = function () {18 reconnect(wsurl);19 };20 ws.onerror = function () {21 reconnect(wsurl);22 };23 ws.onopen = function () {24 //心跳检测重置25 heartcheck.ret().start();26 };27 ws.onmessage = function (event) {28 //如果获取到消息,心跳检测重置29 //拿到任何消息都说明当前连接是正常的30 var data = json.par(event.data);31 if (data.code == 200) {32 console.log(data.message)33 }34 heartcheck.ret().start();35 }36 }37 createwebsocket(wsurl);38 /**39 * 创建链接40 * @param url41 */42 function createwebsocket(url) {43 try {44 ws = new websocket(url);45 initeventhandle();46 } catch (e) {47 reconnect(url);48 }49 }50 function reconnect(url) {51 if(lockreconnect) return;52 lockreconnect = true;53 //没连接上会一直重连,设置延迟避免请求过多54 ttimeout(function () {55 createwebsocket(url);56 lockreconnect = fal;57 }, 2000);58 }59 //心跳检测60 var heartcheck = {61 timeout: 60000,//60秒62 timeoutobj: null,63 rvertimeoutobj: null,64 ret: function(){65 cleartimeout(this.timeoutobj);66 cleartimeout(this.rvertimeoutobj);67 return this;68 },69 start: function(){70 var lf = this;71 this.timeoutobj = ttimeout(function(){72 //这里发送一个心跳,后端收到后,返回一个心跳消息,73 //onmessage拿到返回的心跳就说明连接正常74 ws.nd("heartbeat");75 lf.rvertimeoutobj = ttimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了76 ws.clo();//如果onclo会执行reconnect,我们执行ws.clo()就行了.如果直接执行reconnect 会触发onclo导致重连两次77 }, lf.timeout);78 }, this.timeout);79 },80 header:function(url) {81 window.location.href=url82 }83 84 }85 </script>86 </html>
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta chart="utf-8"> 5 <title>swoole列表页</title> 6 <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,ur-scalable=no"> 7 </head> 8 <body> 9 <h1>swoole列表页</h1>10 </body>11 <script>12 var ws;//websocket实例13 var lockreconnect = fal;//避免重复连接14 var wsurl = 'ws://{{$_rver["http_host"]}}:9502?page=list&token=123456';15 16 function initeventhandle() {17 ws.onclo = function () {18 reconnect(wsurl);19 };20 ws.onerror = function () {21 reconnect(wsurl);22 };23 ws.onopen = function () {24 //心跳检测重置25 heartcheck.ret().start();26 };27 ws.onmessage = function (event) {28 //如果获取到消息,心跳检测重置29 //拿到任何消息都说明当前连接是正常的30 var data = json.par(event.data);31 if (data.code == 200) {32 console.log(data.message)33 }34 heartcheck.ret().start();35 }36 }37 createwebsocket(wsurl);38 /**39 * 创建链接40 * @param url41 */42 function createwebsocket(url) {43 try {44 ws = new websocket(url);45 initeventhandle();46 } catch (e) {47 reconnect(url);48 }49 }50 function reconnect(url) {51 if(lockreconnect) return;52 lockreconnect = true;53 //没连接上会一直重连,设置延迟避免请求过多54 ttimeout(function () {55 createwebsocket(url);56 lockreconnect = fal;57 }, 2000);58 }59 //心跳检测60 var heartcheck = {61 timeout: 60000,//60秒62 timeoutobj: null,63 rvertimeoutobj: null,64 ret: function(){65 cleartimeout(this.timeoutobj);66 cleartimeout(this.rvertimeoutobj);67 return thisyb创业计划书s;68 },69 start: function(){70 var lf = this;71 this.timeoutobj = ttimeout(function(){72 //这里发送一个心跳,后端收到后,返回一个心跳消息,73 //onmessage拿到返回的心跳就说明连接正常74 ws.nd("heartbeat");75 lf.rvertimeoutobj = ttimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了76 ws.clo();//如果onclo会执行reconnect,我们执行ws.clo()就行了.如果直接执行reconnect 会触发onclo导致重连两次77 }, lf.timeout);78 }, this.timeout);79 },80 header:function(url) {81 window.location.href=url82 }83 84 }85 </script>86 </h挂职锻炼tml>
本文发布于:2023-04-08 00:09:21,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/d3c89eaf35e75ec533b2654cad9688f3.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:Laravel 中使用 swoole 项目实战开发案例二 (后端主动分场景给界面推送消息).doc
本文 PDF 下载地址:Laravel 中使用 swoole 项目实战开发案例二 (后端主动分场景给界面推送消息).pdf
留言与评论(共有 0 条评论) |