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语言的设计目标是提供一种能以简易的方式编译.处理低级存储器.产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言.尽 ...
随机推荐
- Java零基础入门之常用工具
Java异常 什么是异常? 在程序运行过程中,意外发生的情况,背离我们程序本身的意图的表现,都可以理解为异常. throwable是所有异常的根类,异常分为两种异常exception和error Er ...
- nginx篇最初级用法之三种虚拟主机基于域名\基于端口\基于IP地址端口的虚拟主机
在nginx中虚拟主机的类型与apache一样也有三种 1.基于域名的虚拟主机 2.基于端口的虚拟主机 3.基于IP地址端口的虚拟主机 在nginx配置文件中每一个server为一个虚拟主机如果需要多 ...
- [考试反思]1005csp-s模拟测试61:休止
连续不知道多少场了,都是一场10名以内一场20以外...波动极大...还极有规律... 拿到这套题,看到T1大模拟无话可说. 然后考场上我觉得T2很简单....然后就码了两个半小时. T3数据水了暴力 ...
- OI 经典诗歌
键盘行 学校机房夜送客,枫叶蒟蒻秋瑟瑟.主人下马客在船,代码欲写无键盘.夜不AC惨将别,别时茫茫屏幕亮. 忽闻楼上键盘声,主人忘归客不发.寻声暗问敲者谁,键盘声停欲语迟.上楼相近邀相见,添酒回灯重开宴 ...
- CSS尺寸样式属性
尺寸样式属性介绍 属性 值 含义 height auto:自动,浏览器会自动计算高度length:使用px定义高度%:基于包含它的块级对象的百分比高度 设置元素高度 width 同上 设置元素的宽度 ...
- 易初大数据——2019年10月17日 王庆超 spss
开放数据库链接是为解决异构数据库间的数据共享而产生, 现已成为WOSA的主要部分和基于windows环境的一种数据库访问接口和标准ODOC为异构数据库访问提供统一接口,允许应用程序以SOL.为数据存取 ...
- PHP根据ip获取地理位置(通过高德地图接口)
PHP根据ip获取地理位置(通过高德地图接口)<pre>//restapi.amap.com/v3/ip?key=2004f145cf3a39a72e9ca70ca4b2a1dc& ...
- Ansibile之playbook初识
一.playbook简介 ansiblie的任务配置文件被称为playbook,俗称“剧本”,每一个剧本(playbook)中都包含了一系列的任务,这每个任务在ansible中又被称为“戏剧”(pla ...
- java中的transient关键字详解
目录 1.何谓序列化? 2.为何要序列化? 3.序列化与transient的使用 4.java类中serialVersionUID作用 5.transient关键字小结 前言 说实话学了一段时间jav ...
- Java虚拟机的内存
JDK1.8之前,java内存分为 线程共享区:堆.方法区.直接内存(非运行时数据区的一部分).线程私有区:程序计数器.虚拟机栈.本地方法栈. JDK1.8开始,虚拟机取消了方法区,改为元空间. 程序 ...