Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)
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", );
self::$server->set([
'worker_num' => ,
'heartbeat_check_interval' => , // 60秒检测一次
'heartbeat_idle_time' => , // 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'] !== "") {
$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;
}, );
}
//心跳检测
var heartCheck = {
timeout: ,//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>
访问前端页面 (显示如下说明前后端链接成功)
以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的官方群点击此处。
Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)的更多相关文章
- Laravel 中使用 swoole 项目实战开发案例二 (后端主动分场景给界面推送消息)
推荐阅读:Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信) 需求分析 我们假设有一个需求,我在后端点击按钮 1,首页弹出 “后端触发了按钮 1”.后端点了 ...
- 知识图谱实战开发案例剖析-番外篇(1)- Neo4j是否支持按照边权重加粗和大数量展示
一.前言 本文是<知识图谱实战开发案例完全剖析>系列文章和网易云视频课程的番外篇,主要记录学员在知识图谱等相关内容的学习 过程中,提出的共性问题进行展开讨论.该部分内容原始内容记录在网易云 ...
- 《Node+MongoDB+React 项目实战开发》已出版
前言 从深圳回长沙已经快4个月了,除了把车开熟练了外,并没有什么值得一提的,长沙这边要么就是连续下一个月雨,要么就是连续一个月高温暴晒,上班更是没啥子意思,长沙这边的公司和深圳落差挺大的,薪资也是断崖 ...
- laravel中的validate验证的使用案例:
第一个是设置,第二个是直接调用.
- .net转php laraval框架学习系列(二)项目实战---Models
上一篇已经介绍开发环境的搭建,如果有问题可以在文章后留言. 这篇将从项目实战开发,一步一步了解laravel框架. 在开发mvc项目时,models都是第一步. 下面就从建模开始. 实体关系图 由于不 ...
- 百度UEditor开发案例(JSP)
本案例的开发环境:MyEclipse+tomcat+jdk 本案例的开发内容: 用百度编辑器发布新闻(UEditor的初始化开发部署) 编辑已发过的新闻(UEditor的应用——编辑旧文章) ...
- CSS3实战开发: 纯CSS实现图片过滤分类显示特效
原文:CSS3实战开发: 纯CSS实现图片过滤分类显示特效 各位网友大家好,今天我要带领大家开发一个纯CSS的图片分类显示的网址导航,单纯看标题大家可能有些困惑,依照以往惯例,我先给大家演示一下实际运 ...
- tp5博客项目实战1
tp5博客项目实战 开发准备:环境wamp,windows系统为例.看实战博客,默认会搭建开发环境并且tp5框架已经至少有一定的基础. tp5的下载与安装 方法一:直接在官网下载拷贝到wamp你的项目 ...
- 基于Linux下的C语言项目实战--本地账号管理系统
C语言开发项目实战: C语言是一门通用计算机编程语言,广泛应用于底层开发.C语言的设计目标是提供一种能以简易的方式编译.处理低级存储器.产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言.尽 ...
随机推荐
- 关于php注释那些事
代码注释的作用 --- 为自己,也为别人. 永远不要过于相信自己的理解力!当你思路通畅,思如泉涌,进入编程境界,你可以很流畅的实现某个功能,但这种一泻千里的流畅可能只停留在了当时的状态.当你几个月, ...
- mysql-清除binlog日志命令
记录一个清除MySQL里binlog日志的命令,可用在定时任务脚本里. 只保留1天前的日志: PURGE MASTER LOGS BEFORE DATE_SUB(CURRENT_DATE, INTER ...
- egret开发方法(最笨的方法)
egret开发方法(最笨的方法)1 1个精灵1个对象名字 获取精灵设置属性也是直接获取对象设置属性 (不用想的少些代码 因为没有jquery好用) ps:如果要设置很多个精灵属性 那可以添加到数组 然 ...
- Nginx使用反向代理实现负载均衡
Nginx使用反向代理实现负载均衡 yls 2019-9-20 简介 基于docker容器以及docker-compose,所以需要自学docker在linux环境的基本使用 使用两个tomcat作为 ...
- shell的运用 : jenkins 编译 打包前端发布 生产(tomcat)
生产隔离做得非常.....文件上传只能通过固定ip机器的sftp账户上传,账户密码每个月要写申请才能获得. 登陆生产服务只能通过浏览器登陆!!! 发布一次生产,很痛苦. 做了简单的shell来减轻痛苦 ...
- 架构设计:"4+1"视图
概念 "4+1"视图,是指从5个不同视角来描述软件体系结构. "4+1"分别指: 逻辑视图 过程视图 物理视图 开发视图 场景/用例 视图 逻辑架构的描述可以围 ...
- Vue img的src使用数据绑定不显示
不少人在vue的开发中遇到这样一个问题: img的src属性绑定url变量,然而图片加载失败. <img src="{{ imgUrl }}"/> 原因:写法错误 解决 ...
- 分组取topN
假设有这样一个文件,文件内容如下 class1 class2 class1 class1 class2 class2 class1 class2 class1 class2 要求按照班级分组取出每个班 ...
- java编程思想第四版第十一章总结
1. 容器类被分为两类:Collection和Map Collection是一个接口:包括: List接口: ArrayList:按照被插入顺序保存元素, 查询快, 增删改慢 LinkedList:按 ...
- 通过canvas合成图片
通过canvas合成图片 效果图 页面布局部分 两个图片以及一个canvas画布 <img src="https://qnlite.gtimg.com/qqnewslite/20190 ...