1 开发需要环境

工欲善其事,必先利其器。在正式开发之前我们检查好需要安装的拓展,不要开发中发现这些问题,打断思路影响我们的开发效率。

  • 安装 swoole 拓展包
  • 安装 redis 拓展包
  • 安装 laravel5.5 版本以上

如果你还不会用swoole就out了

2 Laravel 生成命令行

  1. php artisan make:command SwooleDemo
  1. class SwooleDemo extends Command
  2. {
  3.  
  4. protected $signature = 'swoole:demo';
  5.  
  6. protected $description = '这是关于swoole的一个测试demo';
  7.  
  8. public function __construct()
  9. {
  10. parent::__construct();
  11. }
  12.  
  13. public function handle()
  14. {
  15. $this->line("hello world");
  16. }
  17. }

我们分别运行 php artisan 指令和 php artisan swoole:demo 会看到关于这个命令的说明,和输出 hello world。(laravel 命令行用法详解)

3 命令行逻辑代码

  • 编写一个最基础的 swoole 命令行逻辑代码
  1. <?php
  2.  
  3. namespace App\Console\Commands;
  4.  
  5. use Illuminate\Console\Command;
  6. use Illuminate\Support\Facades\Redis;
  7.  
  8. class SwooleDemo extends Command
  9. {
  10. // 命令名称
  11. protected $signature = 'swoole:demo';
  12. // 命令说明
  13. protected $description = '这是关于swoole websocket的一个测试demo';
  14. // swoole websocket服务
  15. private static $server = null;
  16.  
  17. public function __construct()
  18. {
  19. parent::__construct();
  20. }
  21.  
  22. // 入口
  23. public function handle()
  24. {
  25. $this->redis = Redis::connection('websocket');
  26. $server = self::getWebSocketServer();
  27. $server->on('open',[$this,'onOpen']);
  28. $server->on('message', [$this, 'onMessage']);
  29. $server->on('close', [$this, 'onClose']);
  30. $server->on('request', [$this, 'onRequest']);
  31. $this->line("swoole服务启动成功 ...");
  32. $server->start();
  33. }
  34.  
  35. // 获取服务
  36. public static function getWebSocketServer()
  37. {
  38. if (!(self::$server instanceof \swoole_websocket_server)) {
  39. self::setWebSocketServer();
  40. }
  41. return self::$server;
  42. }
  43. // 服务处始设置
  44. protected static function setWebSocketServer():void
  45. {
  46. self::$server = new \swoole_websocket_server("0.0.0.0", );
  47. self::$server->set([
  48. 'worker_num' => ,
  49. 'heartbeat_check_interval' => , // 60秒检测一次
  50. 'heartbeat_idle_time' => , // 121秒没活动的
  51. ]);
  52. }
  53.  
  54. // 打开swoole websocket服务回调代码
  55. public function onOpen($server, $request)
  56. {
  57. if ($this->checkAccess($server, $request)) {\
  58. self::$server->push($request->fd,"打开swoole服务成功!");\
  59. }
  60. }
  61. // 给swoole websocket 发送消息回调代码
  62. public function onMessage($server, $frame)
  63. {
  64.  
  65. }
  66. // http请求swoole websocket 回调代码
  67. public function onRequest($request,$response)
  68. {
  69.  
  70. }
  71. // websocket 关闭回调代码
  72. public function onClose($serv,$fd)
  73. {
  74. $this->line("客户端 {$fd} 关闭");
  75. }
  76. // 校验客户端连接的合法性,无效的连接不允许连接
  77. public function checkAccess($server, $request):bool
  78. {
  79. $bRes = true;
  80. if (!isset($request->get) || !isset($request->get['token'])) {
  81. self::$server->close($request->fd);
  82. $this->line("接口验证字段不全");
  83. $bRes = false;
  84. } else if ($request->get['token'] !== "") {
  85. $this->line("接口验证错误");
  86. $bRes = false;
  87. }
  88. return $bRes;
  89. }
  90. // 启动websocket服务
  91. public function start()
  92. {
  93. self::$server->start();
  94. }
  95.  
  96. }

编写 websoket js 代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>swoole测试</title>
  6. <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
  7. </head>
  8. <body>
  9. <h1>这是一个测试</h1>
  10. </body>
  11. <script>
  12. var ws;//websocket实例
  13. var lockReconnect = false;//避免重复连接
  14. var wsUrl = 'ws://{{$_SERVER["HTTP_HOST"]}}:9502?page=home&token=123456';
  15.  
  16. function initEventHandle() {
  17. ws.onclose = function () {
  18. reconnect(wsUrl);
  19. };
  20. ws.onerror = function () {
  21. reconnect(wsUrl);
  22. };
  23. ws.onopen = function () {
  24. //心跳检测重置
  25. heartCheck.reset().start();
  26. };
  27. ws.onmessage = function (event) {
  28. //如果获取到消息,心跳检测重置
  29. //拿到任何消息都说明当前连接是正常的
  30. var data = JSON.parse(event.data);
  31. heartCheck.reset().start();
  32. }
  33. }
  34. createWebSocket(wsUrl);
  35. /**
  36. * 创建链接
  37. * @param url
  38. */
  39. function createWebSocket(url) {
  40. try {
  41. ws = new WebSocket(url);
  42. initEventHandle();
  43. } catch (e) {
  44. reconnect(url);
  45. }
  46. }
  47. function reconnect(url) {
  48. if(lockReconnect) return;
  49. lockReconnect = true;
  50. //没连接上会一直重连,设置延迟避免请求过多
  51. setTimeout(function () {
  52. createWebSocket(url);
  53. lockReconnect = false;
  54. }, );
  55. }
  56. //心跳检测
  57. var heartCheck = {
  58. timeout: ,//60秒
  59. timeoutObj: null,
  60. serverTimeoutObj: null,
  61. reset: function(){
  62. clearTimeout(this.timeoutObj);
  63. clearTimeout(this.serverTimeoutObj);
  64. return this;
  65. },
  66. start: function(){
  67. var self = this;
  68. this.timeoutObj = setTimeout(function(){
  69. //这里发送一个心跳,后端收到后,返回一个心跳消息,
  70. //onmessage拿到返回的心跳就说明连接正常
  71. ws.send("heartbeat");
  72. self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了
  73. ws.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
  74. }, self.timeout);
  75. }, this.timeout);
  76. },
  77. header:function(url) {
  78. window.location.href=url
  79. }
  80.  
  81. }
  82. </script>
  83. </html>
  84. 访问前端页面 (显示如下说明前后端链接成功)

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的官方群点击此处

Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)的更多相关文章

  1. Laravel 中使用 swoole 项目实战开发案例二 (后端主动分场景给界面推送消息)

    推荐阅读:Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)​ 需求分析 我们假设有一个需求,我在后端点击按钮 1,首页弹出 “后端触发了按钮 1”.后端点了 ...

  2. 知识图谱实战开发案例剖析-番外篇(1)- Neo4j是否支持按照边权重加粗和大数量展示

    一.前言 本文是<知识图谱实战开发案例完全剖析>系列文章和网易云视频课程的番外篇,主要记录学员在知识图谱等相关内容的学习 过程中,提出的共性问题进行展开讨论.该部分内容原始内容记录在网易云 ...

  3. 《Node+MongoDB+React 项目实战开发》已出版

    前言 从深圳回长沙已经快4个月了,除了把车开熟练了外,并没有什么值得一提的,长沙这边要么就是连续下一个月雨,要么就是连续一个月高温暴晒,上班更是没啥子意思,长沙这边的公司和深圳落差挺大的,薪资也是断崖 ...

  4. laravel中的validate验证的使用案例:

    第一个是设置,第二个是直接调用.

  5. .net转php laraval框架学习系列(二)项目实战---Models

    上一篇已经介绍开发环境的搭建,如果有问题可以在文章后留言. 这篇将从项目实战开发,一步一步了解laravel框架. 在开发mvc项目时,models都是第一步. 下面就从建模开始. 实体关系图 由于不 ...

  6. 百度UEditor开发案例(JSP)

    本案例的开发环境:MyEclipse+tomcat+jdk     本案例的开发内容: 用百度编辑器发布新闻(UEditor的初始化开发部署) 编辑已发过的新闻(UEditor的应用——编辑旧文章) ...

  7. CSS3实战开发: 纯CSS实现图片过滤分类显示特效

    原文:CSS3实战开发: 纯CSS实现图片过滤分类显示特效 各位网友大家好,今天我要带领大家开发一个纯CSS的图片分类显示的网址导航,单纯看标题大家可能有些困惑,依照以往惯例,我先给大家演示一下实际运 ...

  8. tp5博客项目实战1

    tp5博客项目实战 开发准备:环境wamp,windows系统为例.看实战博客,默认会搭建开发环境并且tp5框架已经至少有一定的基础. tp5的下载与安装 方法一:直接在官网下载拷贝到wamp你的项目 ...

  9. 基于Linux下的C语言项目实战--本地账号管理系统

    C语言开发项目实战: C语言是一门通用计算机编程语言,广泛应用于底层开发.C语言的设计目标是提供一种能以简易的方式编译.处理低级存储器.产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言.尽 ...

随机推荐

  1. 【Java】Windows配置Java环境变量

    一.配置环境变量 1.新建系统变量 JAVA_HOME和CLASSPATH 变量名:JAVA_HOME 变量值:D:\jdk\jdk1.7.0_80 变量名:CLASSPATH 变量值:.;%JAVA ...

  2. [2018-10-29] python开发个人资源共享网--第二天

    创建Django目录 startproject my_project 创建APP startapp my_app 手动创建的文件夹 log 日志 media 用户上传下载 static 静态文件 配置 ...

  3. python机器学习——自适应线性神经元

    上篇博客我们说了感知器,这篇博客主要记录自适应线性神经元的实现算法及一些其他的训练细节,自适应线性神经元(简称为Adaline)由Bernard Widrow和他的博士生Tedd Hoff提出,对感知 ...

  4. NOIP 模拟29 B 侥幸

    这次考得好纯属是侥幸,我T3打表试数试了两个小时,没有想打T2的正解(其实是打不出来)所以这个T3A掉纯属是侥幸,以后还是要打正解 (以下博客最好按全选观看,鬼知道为啥这个样子!) 在这里也口胡一下我 ...

  5. python_day3(文件处理)

    1.文件处理 #Author:Elson Zeng #data = open("test").read() # f = open("test",'a',enco ...

  6. python基础-面向过程编程

    面向过程编程 面向过程编程其实是一种机械式的思维方式,其核心就是"过程". 过程指的是一种解决问题的步骤,即先干什么再干什么,最后干什么. 优点:将复杂的问题流程化,进而简单化. ...

  7. SpringBoot之微服务日志链路追踪

    SpringBoot之微服务日志链路追踪 简介 在微服务里,业务出现问题或者程序出的任何问题,都少不了查看日志,一般我们使用 ELK 相关的日志收集工具,服务多的情况下,业务问题也是有些难以排查,只能 ...

  8. spring security 简单入门

    spring security 简单入门示例 一.概述 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架 . 其中最主要的安全操作有两 ...

  9. Geometry 判断几何是否被另一个几何/线段分割成多段

    如下图,如何判断几何多边形A被多边形B,切割为多段几何? 几何A被几何B切割 1. 获取几何A与几何B的交集C var intersectGeometry = new CombinedGeometry ...

  10. 020.掌握Pod-Pod基础使用

    一 Pod定义详解 1.1 完整Pod定义文件 apiVersion: v1 #必选,版本号,例如v1,版本号必须可以用 kubectl api-versions 查询到 kind: Pod #必选, ...