使用swoole实现实时消息推送给客户端
一. 测试服务端
//测试服务端public function testServer(){$server = new Server('192.168.0.144', 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP);$server->on('request', function ($request, $response) {$response->header('Content-Type', 'text/plain');$response->end("Hello, Swoole!");});$server->start();}
二. 服务端 , 本服务端使用 swoole-v2.2.0, 推送主代码
<?php
namespace app\index\controller;
use think\Db;
use Swoole\Http\Server;
use Swoole\WebSocket\Server as ServerSocket;
use Swoole\Timer;//启动服务端,将满足条件的数据推送public function notificationServer(){$server = new ServerSocket('192.168.0.144', 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP);$timerCallback = function () use ($server) {$results = Db::name('scores')->where('uid', '=', 9)->find();$score = $results['score'];// 判断分数是否达到60分if ($score >= 60) {// 向所有连接的客户端发送通知和成绩单$message = "您的成绩已经合格,请去考试中心打印成绩单";} else {$message = "您的成绩不合格,请下次继续努力呢";}foreach ($server->connections as $fd) {$server->push($fd, $message);}};$server->on('open', function ($server, $request) use ($timerCallback) {echo "WebSocket连接建立成功\n";// 启动定时器,每隔5秒触发一次$timerId = Timer::tick(500, $timerCallback);$server->wsTimerId = $timerId;});$server->on('message', function ($server, $frame) {echo "收到消息:{$frame->data}\n";// $server->push($frame->fd, "服务器收到了你的消息:{$frame->data}");});$server->on('close', function ($server, $fd) {echo "WebSocket连接关闭\n";// 清除定时器Timer::clear($server->wsTimerId);});$server->start();}
三.启动服务端
php public/index.php index/index/notificationServer > /dev/null 2>&1 &
或者
php public/index.php index/index/notificationServer
可以用路由
四 数据库

五.客户单web代码
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>WebSocket Client</title><!-- 导入jQuery库 --><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script><style>.red-bubble {display: none; /* 初始时隐藏气泡 */position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);padding: 10px;background-color: red;color: white;font-weight: bold;border-radius: 5px;}</style>
</head>
<body><div id="redBubble" class="red-bubble"></div><script>var socket = new WebSocket("ws://192.168.0.144:9501");var redBubble = $("#redBubble");socket.onopen = function() {console.log("WebSocket connection established.");};// socket.onopen = function() {// console.log("WebSocket connection established.");// // 连接建立后发送消息// var messageToSend = "Hello, server!";// socket.send(messageToSend);// };socket.onmessage = function(event) {console.log(event);var message = event.data;console.log("Received message: " + message);// 显示气泡并缓慢显示redBubble.text(message).fadeIn("slow");// 5秒后缓慢消失setTimeout(function() {redBubble.fadeOut("slow");}, 5000);};socket.onclose = function(event) {console.log("WebSocket connection closed with code: " + event.code);};</script>
</body>
</html>
效果

ps:若要实现指定用户推送请参考下面的代码, 通过 session(‘uid’) 获取到当前用户的用户ID,并将其与连接标识进行映射。在收到消息时,获取目标用户的用户ID,并根据用户ID找到对应的连接标识,然后向该连接标识对应的用户推送消息。
use Swoole\WebSocket\Server;// 创建全局数组用于存储连接标识与用户ID的映射关系
$connections = [];$server = new Server('0.0.0.0', 9501);$server->on('open', function (Server $server, $request) use (&$connections) {// 获取用户ID$userId = session('uid');// 将连接标识与用户ID的映射关系保存到全局数组中$connections[$request->fd] = $userId;echo "用户ID为{$userId}的用户已连接\n";
});$server->on('message', function (Server $server, $frame) use (&$connections) {echo "收到消息:{$frame->data}\n";// 获取要推送的用户ID$targetUserId = session('uid');// 通过用户ID找到对应的连接标识foreach ($connections as $fd => $userId) {if ($userId === $targetUserId) {// 向指定用户推送消息$server->push($fd, $message);}}
});$server->on('close', function (Server $server, $fd) use (&$connections) {// 从数组中移除断开连接的映射关系unset($connections[$fd]);echo "连接标识为{$fd}的用户已断开连接\n";
});$server->start();
在该示例中,我们通过 session(‘uid’) 获取到当前用户的用户ID,并将其与连接标识进行映射。在收到消息时,获取目标用户的用户ID,并根据用户ID找到对应的连接标识,然后向该连接标识对应的用户推送消息。
相关文章:
使用swoole实现实时消息推送给客户端
一. 测试服务端 //测试服务端public function testServer(){$server new Server(192.168.0.144, 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP);$server->on(request, function ($request, $response) {$response->header(Content-Type, text/plain);$response->end("He…...
Ordinals 之后,以太坊铭文协议 Ethscriptions 如何再塑 NFT 资产形态
随着加密市场的发展,NFT 赛道逐渐形成了其独有的市场。但在加密熊市的持续影响下,今年 NFT 赛道的发展充满坎坷与挑战。据 NFTGO 数据显示,截至 8 月 7 日,与去年相比,NFT 市值总计约 56.4 亿美元,过去 1 年…...
Python绘制爱心代码(七夕限定版)
写在前面: 又到了一年一度的七夕节啦!你还在发愁送女朋友什么礼物,不知道怎样表达你满满的爱意吗?别担心,我来帮你!今天,我将教你使用Python绘制一个跳动的爱心,用创意和幽默为这个…...
Java两整数相除向上取整
方法一:通过三目运算符 (简单移动) x / y (x % y ! 0 ? 1 : 0);方法二:通过ceil函数(不推荐使用,涉及类型转换) (int)Math.ceil((double)x/y);// 或者(int)Math.ceil(x * 1.0 /y);方法三&…...
Linux学习之Telnet明文漏洞
yum install telnet telnet-server xinetd -y安装软件。 systemctl start xinetd.service开启xinetd,systemctl start telnet.socket开启telnet。 xinetd来监控端口,然后把数据传给telnet。 ifconfig eth0看一下eth0网卡信息,。 iptable…...
产品经理如何提高用户画像效果?SIKT模型
产品经理做用户画像,最担心被业务方反馈:没效果。这往往是由用户画像与业务场景脱节造成的。那么我们该如何从业务场景出发,让用户画像更有效?一般来说,我们可以采用SIKT模型解决这个问题。 用户画像 1、SIK…...
ubuntu安装Microsoft Edge并设置为中文
1、下载 edge.deb 版本并安装 sudo dpkg -i microsoft-edg.deb 2. 设置默认中文显示 如果是通过.deb方式安装的: 打开默认安装路径下的microsoft-edge-dev文件,在文件最开头加上: export LANGUAGEZH-CN.UTF-8 ,保存退出。 cd /opt/micr…...
Host/ KVM/ Docker/ K8s/ OpenStack/ Mesos简单介绍和区别
Host/ KVM/ Docker/ Kubernetes/ OpenStack 和 Mesos 的简单介绍: - Host: Host 是指物理服务器或虚拟机主机,它们可以运行多个虚拟机或容器来提供计算和存储资源。Host 是云计算和容器化技术中的基本组成部分。 - KVM: KVM 是…...
关于Transformer中的位置编码
位置编码 (Positional Encoding) 位置编码是在自然语言处理中,特别是在 Transformer 架构中使用的一个重要概念。Transformer 架构由于其自注意力机制 (Self-Attention Mechanism) 的特性,对序列中的元素没有固有的顺序感知。这意味着,如果不…...
ABAP 期初库存批量导入 demo1
&--------------------------------------------------------------------- *& Report ZMMCP005 &--------------------------------------------------------------------- 作者: Liv完成日期:描述: 期初库存导入需求简要说明&…...
想用 Python 写游戏,都有哪些好用的游戏开发库?
虽然 Python 在网络爬虫、人工智能、数据分析方面有广泛应用,但它并不是一门专门做游戏开发的编程语言,不过对于小型的游戏开发,Python 还是挺香的。下面为大家介绍几个支持 Python 的 2D、3D 游戏开发库,使用它们,你可以设计出很多有意思的小游戏! Cocos2d Cocos2d 是…...
vue3 路由缓存问题
目录 解决问题的思路: 解决问题的方案: 1、给roter-view添加key(破坏复用机制,强制销毁重建) 2、使用beforeRouteUpdate导航钩子 3、使用watch监听路由 vue3路由缓存:当用户从/users/johnny导航到/use…...
如何找到一个数的所有质因数,以及如何快速判断一个数是不是质数
前情介绍 今天遇到一个需求:找到一个数所有的质因数。 初步解决 先定义一个判断质数的函数: def is_Prime(number):i 2count 0while i < number:if number % i 0 :count 1i 1if count > 0:return Falseelse:return True 接着定义一个寻找质…...
西瓜书之神经网络
一,神经元模型 所谓神经网络, 目前用得最广泛的一个定义是“神经网络是由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够模拟生物神经系统对真实世界物体所做出的交互反应”。 M-P神经元 M-P神经元:接收n个输入(…...
C++进阶 特殊类的设计
本篇博客介绍:介绍几种特殊的类 特殊类的设计 设计一个类不能被拷贝设计一个类 只能在堆上创建对象设计一个类 只能在栈上创造对象设计一个类不能被继承单例模式饿汉模式懒汉模式单例模式对象的释放问题 总结 设计一个类不能被拷贝 我们的拷贝只会发生在两个场景当…...
NLP序列标注问题,样本不均衡怎么解决?
【学而不思则罔,思而不学则殆】 1.问题 NLP序列标注问题,样本不均衡怎么解决? 2.解释 以命名实体识别(NER)为例,这个样本不均衡有两种解释: (1)实体间类别数量不均衡…...
大端和小端
大端和小端 大端(Big Endian)和小端(Little Endian)是两种不同的字节序排列方式,用于解释多字节数据在内存中的存储顺序。 在大端字节序中,高位字节(最高有效位)存储在低位地址&am…...
C++快速回顾(二)
前言 在Android音视频开发中,网上知识点过于零碎,自学起来难度非常大,不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》,结合我自己的工作学习经历,我准备写一个音视频系列blog。C/C是音视频必…...
【LVS】1、LVS负载均衡群集
1.群集的含义: Cluster、群集、集群 由多台主机构成并作为一个整体,只提供一个访问入口(域名与IP地址);可伸缩 2.集群使用的场景: 高并发 3.企业群集的分类: 根据群集所针对的目标差异&a…...
el-tree 懒加载树
el-tree 懒加载树 添加自定义图标指定叶子节点懒加载 <template><div><el-treeclass"filter-tree":data"treeData":props"defaultProps"ref"tree"lazy:load"loadTree":expand-on-click-node"true"…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
麒麟系统使用-进行.NET开发
文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的,如果需要进行.NET开发,则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET,所以要进…...
Python的__call__ 方法
在 Python 中,__call__ 是一个特殊的魔术方法(magic method),它允许一个类的实例像函数一样被调用。当你在一个对象后面加上 () 并执行时(例如 obj()),Python 会自动调用该对象的 __call__ 方法…...
【题解-洛谷】P10480 可达性统计
题目:P10480 可达性统计 题目描述 给定一张 N N N 个点 M M M 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。 输入格式 第一行两个整数 N , M N,M N,M,接下来 M M M 行每行两个整数 x , y x,y x,y,表示从 …...
