【旧文搬运】为你的 Laravel 应用添加一个基于 Swoole 的 WebSocket 服务

做了一个基于 Swoole 的 WebSocket 扩展包,可以用来做实时状态推送,或者自定义消息处理实现 im,有需要的可以看看: [giorgio-socket]

在这里插入图片描述

使用方法

安装

安装扩展包

composer require wu/giorgio-socket

发布配置文件

php artisan vendor:publish --provider="GiorgioSocket\Providers\SocketServiceProvider"

运行 Socket 服务

php artisan socket:start

注意事项

  • 可以通过实现 GiorgioSocket\Services\Handlers\Interfaces 下的接口类来自定义自己的业务逻辑。

  • 如果要从服务端发送消息,这里有两种方式:

    • 第一种,借助 Laravel HTTP 客户端
      Route::get('/socket', function () {
          \Illuminate\Support\Facades\Http::asForm()->post('http://127.0.0.1:9501', [
              'to' => 2,
              'message' => 'server message',
          ]);
      });
      
    • 第二种:借助 Laravel Listener,需要将 .env 文件中的 QUEUE_CONNECTION 配置修改为 redis 或其他异步队列。配置更改后,运行以下命令:php-artisan queue:work --queue=socket-listener监听队列,然后按以下代码调用 event
      Route::any('socket', function (Request $request){
          \GiorgioSocket\Events\SocketEvent::dispatch($request->get('to'), $request->get('message'));
      });
      
  • 如果你正在使用 laravel/breeze 扩展包,并且使用了 Blade 模板,可以将以下代码粘贴到 dashboard.blade.php 中进行快速测试:

      @auth
          <div class="py-12">
              <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
                  <div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
                      <div class="grid grid-cols-1 md:grid-cols-2">
                          <div class="p-6" id="server-message">
                              messages:<br/>
                          </div>
    
                          <div class="p-6">
                              <label class="block font-medium text-sm text-gray-700 dark:text-gray-300" for="from">from</label>
                              <input class="border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm block mt-1 w-full" value="{{ auth()->user()->getKey() }}" id="from">
                              <label class="block font-medium text-sm text-gray-700 dark:text-gray-300" for="to">to</label>
                              <input class="border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm block mt-1 w-full" value="" id="to">
                              <label class="block font-medium text-sm text-gray-700 dark:text-gray-300" for="message">message</label>
                              <textarea class="border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm block mt-1 w-full" id="message"></textarea>
                              <input class="inline-flex items-center px-4 py-2 bg-gray-800 dark:bg-gray-200 border border-transparent rounded-md font-semibold text-xs text-white dark:text-gray-800 uppercase tracking-widest hover:bg-gray-700 dark:hover:bg-white focus:bg-gray-700 dark:focus:bg-white active:bg-gray-900 dark:active:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150 mt-3" type="button" id="submit" value="submit">
                          </div>
                      </div>
                  </div>
              </div>
          </div>
          <script type="text/javascript">
            let heartBeatTimer = 0;
            let socket = connectWebSocket();
    
            function startHeartbeat(interval) {
              interval = interval || 30;
              heartBeatTimer = setInterval(function () {
                sendMessage(null, "heart_beat");
              }, interval * 1000);
            }
    
            function stopHeartbeat() {
              clearInterval(heartBeatTimer);
            }
    
            function connectWebSocket() {
              const wsServer = 'ws://127.0.0.1:9501';
              const socket = new WebSocket(wsServer);
    
              let userId = document.getElementById('from').value;
              socket.onopen = function (evt) {
                let data = {
                  user_id: userId,
                  type: 'connect'
                };
                console.log('open', data)
                socket.send(JSON.stringify(data));
              };
    
    
              socket.onmessage = function (evt) {
                console.log('get message from server: ' + evt.data);
    
                if (evt.data !== 'heart_beat') {
                  let data = JSON.parse(evt.data);
                  let message = document.getElementById("server-message")
                  message.innerHTML += data.user_name + ': ' + data.data + '<br/>'
                }
              };
    
              socket.onerror = function (evt) {
                console.log(evt);
              };
    
              socket.onclose = function () {
                let data = {
                  user_id: userId,
                  type: 'close'
                };
                socket.send(JSON.stringify(data));
              };
              return socket;
            }
    
            function sendMessage(to, message) {
              if (socket != null && socket.readyState === WebSocket.OPEN) {
                if (message !== 'heart_beat') {
                  let messageBox = document.getElementById("server-message")
                  messageBox.innerHTML += 'me: ' + message + '<br/>'
                }
                let from = document.getElementById("from")
                socket.send(JSON.stringify({
                  user_id: from.value,
                  user_name: '{{ auth()->user()->name }}',
                  to: to,
                  type: 'message',
                  data: message,
                }));
                console.log("webSocket send message:" + JSON.stringify({
                  user_id: from.value,
                  user_name: '{{ auth()->user()->name }}',
                  to: to,
                  type: 'message',
                  data: message,
                }));
              } else {
                console.log("webSocket closed");
              }
            }
    
            let button = document.getElementById("submit");
            button.addEventListener('click', function () {
              let message = document.getElementById("message");
              let to = document.getElementById("to");
              sendMessage(to.value, message.value)
            });
    
          </script>
      @endauth
    

    如有任何疑问,欢迎提交 [issue]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/425506.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习:数据处理基操

在处理完数据之后&#xff0c;选择好模型&#xff0c;就可以用训练集训练模型&#xff0c;用测试集输入模型 然后输出需要预测的结果啦&#xff5e; 一、模块导入 import numpy as np import pandas as pd #读入数据 二、pandas数据 一、dataframe基础 一、dataframe的创建…

图像处理ASIC设计方法 笔记6 数据拼接和帧格式校正

第四章大模板卷积ASIC设计方案 P80 实时图SPRM 数据位宽64bit,4个SPRAM,同时得到4行数据 绘制卷积芯片数据路径图,卷积芯片内部模块图 根据这个图,本书后续对各个模块都进行介绍。 P81 第一个模块 图像输入前端FIFO 学习图像处理中好的设计思路:帧格式校验和数据拼接 …

STM32+ESP8266水墨屏天气时钟:ESP8266连接心知天气获取数据

项目背景 利用STM32F103C8T6和ESP8266模块进行通信&#xff0c;获取心知天气的数据。 硬件设计为串口1(PA9和PA10)连接ESP8266. 串口2打印 一.ESP8266连接WIFI ESP8266模块可以通过AT指令控制搭配使用源代码API函数开发&#xff0c;总体开发速度快&#xff0c;难度较低。 说…

板子合集1.0

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 原文链接&#xff1a;https://blog.csdn.net/JK01WYX/ 文章目录 1.快速幂板子2.gcd得最大公约数3.堆优化的dijkstra板子4.线段树1板子 区间加线段…

Vue--》打造简易直播应用平台项目实战

今天开始使用 vue3 + ts 搭建一个简易直播应用平台项目,因为文章会将项目的每一个地方代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的github上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关注本…

奇怪的需求之与图片做交互

1.起因 客户想要展示自己的地图,该地图上有各种工作数据,和工作点位,已有的地图不能满足需求.于是提出将这张图片当成大背景 2.经过 鉴于文件格式和尺寸的原因,协商后客户提出将图片做成缩放效果,同时具有点击效果,原先直接进入的主页,现在为点击图片中的某条线路进入主页面…

【论文阅读】多传感器SLAM数据集

一、M2DGR 该数据集主要针对的是地面机器人&#xff0c;文章正文提到&#xff0c;现在许多机器人在进行定位时&#xff0c;其视角以及移动速度与车或者无人机有着较大的差异&#xff0c;这一差异导致在地面机器人完成SLAM任务时并不能直接套用类似的数据集。针对这一问题该团队…

Sentinel 规则持久化,基于Redis持久化【附带源码】

B站视频讲解 学习链接&#x1f517; 文章目录 一、理论二、实践2-1、dashboard 请求Redis2-1-1、依赖、配置文件引入2-1-2、常量定义2-1-3、改写唯一id2-1-4、新Provider和Publisher2-1-5、改写V2 2-2、应用服务改造2-2-1、依赖、配置文件引入2-2-2、注册监听器 三、源码获取3…

从0到1实现自助棋牌室系统:技术调研

前言 春节返乡之际&#xff0c;发现老家县城竟然开了近十家棋牌室。巧的是朋友也有意涉足&#xff0c;便咨询我自助棋牌室的软件投入成本。作为程序员的我&#xff0c;在思考了自助棋牌室背后的技术需求后&#xff0c;嗅到了一丝丝商机&#xff1a;何不自己开发一个自助棋牌室…

操作系统的运行机制

目录 一. 特权指令与非特权指令二. 中断和异常2.1. 内中断2.2 外中断 三. 系统调用 注:很多人习惯把Linux、Windows、MacOS的“小黑框”中使用的命令也称为“指令”&#xff0c;其实这是“交互式命令接口”&#xff0c;注意与本节的“指令”区别开。本节中的“指令”指二进制机…

jenkins实战(1)

一, Jenkins官网介绍: Jenkins 持续集成、持续部署 下载地址:Jenkins download and deployment 提供两种类型: LTS(长期版)和Weekly(最近一周的版本) 注: 必须是Java8及以上版本(官网针对这一点有做说明) 二, 安装 下载war包,java -jar XXX --httpPort8081 或 下载war包…

Linux:kubernetes(k8s)搭建mater节点(kubeadm,kubectl,kubelet)(2)

安装k8有多种方式如&#xff1a; minikube kubeadm 二进制安装 命令行工具 我这里就使用kubeadm进行安装 环境 3台centos7 master ip &#xff1a;192.168.113.120 2G运存 2内核 node1 ip &#xff1a;192.168.113.121 2G运存 2内核 node2 ip &#xff1a;192.168.1…

Myqsort:基于冒泡排序算法的C语言实现

我们将详细介绍一个基于冒泡排序算法的自定义排序函数——Mysqrt。该函数通过使用用户提供的比较函数进行元素间的比较&#xff0c;并结合swap交换函数对任意类型的数据进行排序。下面是对代码的逐行解析。 逻辑导图 代码实现 // 头文件 #include<stdio.h>// 定义比较函…

关于uniapp小程序的分包问题

开发uniapp小程序时&#xff0c;在打包上传代码时会出现超出2M的打包限制不能上传&#xff0c;那么我们该怎么做呢&#xff1f; 1.对于图片&#xff0c;将图片从后端服务取&#xff0c;尽量不要放在静态资源&#xff0c;图片体积会影响打包大小。 2.使用分包&#xff0c;tabb…

SSH教程

ssh 是远程连接的利器, 可以说凡是涉及到 linux 服务器, ssh 就是一个绕不开的话题. 本文作为一个教程, 尽可能详细的帮助读者设置 ssh, 并给出一些常用的 ssh 配置方法 (主要用于 linux 系统的远程登录和文件传输). 1. 简介 ssh 分为两个部分, sshd 服务端和 ssh 客户端. ssh…

2024-02学习笔记

1.当我们向Set集合中添加一个已经存在的元素时 当我们向Set集合中添加一个已经存在的元素时&#xff0c;Set集合会如何处理呢&#xff1f;实际上&#xff0c;Set集合不会将重复的元素添加到集合中。当我们向Set集合中添加一个元素时&#xff0c;Set集合会首先判断该元素是否已…

[C++]C++使用yolov9结合bytetrack实现目标追踪演示

【简介】 在C中实现YOLOv9的目标检测与ByteTrack的多目标追踪是一个相对复杂的过程&#xff0c;涉及到深度学习、计算机视觉和实时数据处理等多个领域。下面我将简单介绍这两个技术&#xff0c;并概述如何在C中实现它们。 YOLOv9&#xff08;You Only Look Once&#xff0c;版…

STL常见容器(map/multimap容器)---C++

STL常见容器目录&#xff1a; 8.map/ multimap容器8.1 map基本概念8.2 map构造和赋值8.3 map大小和交换8.4 map插入和删除8.5 map查找和统计8.6 map容器排序8.6.1 内置类型排序8.6.2 自定义类型排序8.6.3 自定义和内置类型混合排序 8.7 实例8.7.1 案例描述8.7.2 实现步骤 8.map…

Vue.js+SpringBoot开发高校实验室管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实验管理模块2.4 实验设备模块2.5 实验订单模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示五、样例代码5.1 查询实验室设备5.2 实验放号5.3 实验预定 六、免责说明 一、摘…