使用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找到对应的连接标识,然后向该连接标识对应的用户推送消息。

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

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

相关文章

小白的Node.js学习笔记大全---不定期更新

Node.js是什么 Node. js 是一个基于 Chrome v8 引擎的服务器端 JavaScript 运行环境Node. js 是一个事件驱动、非阻塞式I/O 的模型&#xff0c;轻量而又高效Node. js 的包管理器 npm 是全球最大的开源库生态系统 特性 单一线程 Node.js 沿用了 JavaScript 单一线程的执行特…

Collada .dae文件格式简明教程【3D】

当你从互联网下载 3D 模型时&#xff0c;可能会在格式列表中看到 .dae 格式。 它是什么&#xff1f; 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景。 1、Collada DAE概述 COLLADA是COLLAborative Design Activity&#xff08;中文&#xff1a;协作设计活动&#xff09…

高效解决Anaconda Prompt报错Did not find VSINSTALLDIR这类问题

文章目录 回忆问题解决问题step1step2 回忆问题 类似于划红线部分然后还有很多行的报错信息&#xff0c;最后一行肯定是红色划线部分 解决问题 step1 找到 D:\Anaconda\envs\pytorch\etc\conda\activate.d在这个文件夹内会有两个文件&#xff0c;删除 vs2017_compiler_v…

vue3生命周期

原理 vue3也提供了Composition API形式的生命周期钩子&#xff0c;与vue2.x中钩子对应关系如下&#xff1a; beforeCreate setup&#xff08;&#xff09; created setup&#xff08;&#xff09; beforeMountonBeforeMount mountedonMounted beforeUpdateonBeforeUpdate updat…

AI百度文心一言大语言模型接入使用(中国版ChatGPT)

百度文心一言接入使用&#xff08;中国版ChatGPT&#xff09; 一、百度文心一言API二、使用步骤1、接口2、请求参数3、请求参数示例4、接口 返回示例 三、 如何获取appKey和uid1、申请appKey:2、获取appKey和uid 四、重要说明 一、百度文心一言API 基于百度文心一言语言大模型…

【MaxKey对接一】对接gitlab的oauth登录

MaxKey的Oauth过程 引导进入 GET http://{{maxKey_host}}/sign/authz/oauth/v20/authorize?client_idYOUR_CLIENT_ID&response_typecode&redirect_uriYOUR_REGISTERED_REDIRECT_URI 登录后回调地址 YOUR_REGISTERED_REDIRECT_URI/?code{{code}} 换取Access Token GET…

React 调试开发插件 React devtools 的使用

可以在谷歌扩展应用商店里获取这个插件。如果不能访问谷歌应用商店&#xff0c;可以点此下载最新版 安装插件后&#xff0c;控制台出现 “Components” 跟 “Profiler” 菜单选项。 查看版本&#xff0c;步骤&#xff1a; 下面介绍 react devtools 的使用方式。 在 Component…

安装jenkins-cli

1、要在 Linux 操作系统上安装 jcli curl -L https://github.com/jenkins-zh/jenkins-cli/releases/latest/download/jcli-linux-amd64.tar.gz|tar xzv sudo mv jcli /usr/local/bin/ 在用户根目录下&#xff0c;增加 jcli 的配置文件&#xff1a; jcli config gen -ifalse …

如何快速制作解决方案PPT

如何快速制作解决方案PPT 理解客户的需求 在开始制作解决方案PPT之前&#xff0c;需要对客户的需求进行深入了解和分析。这包括客户需要解决的问题、目标、预算和时间限制等。 需求分析 客户需要解决的问题客户的目标预算限制时间限制 确定解决方案 基于客户的需求&#x…

小程序-基于vant的Picker组件实现省市区选择

一、原因 因vant/area-data部分的市/区数据跟后台使用的高德/腾讯省市区有所出入&#xff0c;故须保持跟后台用同一份数据&#xff0c;所以考虑以下几个组件 1、Area 2、Cascader 3、Picker 因为使用的是高德地图的省市区json文件&#xff0c;用area的话修改结构代价太大&…

2023年Java核心技术面试第五篇(篇篇万字精讲)

目录 十 . HashMap&#xff0c;ConcurrentHashMap源码解析 10.1 HashMap 的源码解析&#xff1a; 10.1.1数据结构&#xff1a; 10.1.2哈希算法&#xff1a; 10.1.3解决哈希冲突&#xff1a; 10.1.4扩容机制&#xff1a; 10.1.5如何使用 HashMap&#xff1a; 10.2 HashMap 关注…

小程序 CSS-in-JS 和原子化的另一种选择

小程序 CSS-in-JS 和原子化的另一种选择 小程序 CSS-in-JS 和原子化的另一种选择 介绍快速开始 pandacss 安装和配置 0. 安装和初始化 pandacss1. 配置 postcss2. 检查你的 panda.config.ts3. 修改 package.json 脚本4. 全局 css 注册 pandacss5. 配置的优化与别名 weapp-pand…

数学建模的概念和学习方法(什么是数学建模)

一、初步认识数学建模 数学建模是将数学方法和技巧应用于实际问题的过程。它涉及使用数学模型来描述和分析现实世界中的现象、系统或过程&#xff0c;并通过数学分析和计算来预测、优化或解决问题。数学建模可以应用于各种领域&#xff0c;包括自然科学、工程、经济学、环境科学…

微服务—远程调用(RestTemplate)

在微服务的所有框架中&#xff0c;SpringCloud脱颖而出&#xff0c;它是目前国内使用的最广泛的微服务框架 &#xff08;官网地址&#xff09;&#xff0c;它集成了各种微服务功能组件&#xff0c;并基于SpringBoot实现了这些组件的自动装配&#xff0c;从而提供了良好的开箱…

【激光雕刻与DIY Arduino SCARA机器人】

【激光雕刻与DIY Arduino SCARA机器人】 1. 项目概况2. 设计和3D模型3. 安装激光模块4. SCARA机器人激光雕刻机电路图5. 完成装配6. 马林固件,用于使用 SCARA 机器人进行激光雕刻7. 配置 Marlin 固件8. 控制软件 – 主机9. 使用 SCARA 机器人进行激光雕刻10. 生成用于激光雕刻…

wkhtmltopdf 与 .Net Core

wkhtmltopdf 是使用webkit引擎转化为pdf的开源小插件. 其有.NET CORE版本的组件,DinkToPdf,但该控件对跨平台支持有限 。 是由于各系统平台会产生不同的编译结果,故windows上使用.dll,而Linux上的动态链接库是.so 所以你需要在Linux系统上安装相关wkhtmltox软件。 我这里准备了…

【Linux命令详解 | wget命令】 wget命令用于从网络下载文件,支持HTTP、HTTPS和FTP协议

文章标题 简介一&#xff0c;参数列表二&#xff0c;使用介绍1. 基本文件下载2. 递归下载整个网站3. 限制下载速率4. 防止SSL证书校验5. 断点续传6. 指定保存目录7. 自定义保存文件名8. 增量下载9. 使用HTTP代理10. 后台下载 总结 简介 在编程世界中&#xff0c;处理网络资源是…

前端技术栈es6+promise

let入门使用、 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>let 基本使用</title><script type"text/javascript">let name "hspedu教育";//老韩解读//1. conso…

第六次作业 运维高级 docker容器

1.安装docker服务&#xff0c;配置镜像加速器 卸载旧版本 yum remove docker docker-common docker-selinux docker-engine使用yum源安装 &#xff08;1&#xff09;安装Docker所需要的一些工具包 yum install -y yum-utils&#xff08;2&#xff09; 建立Docker仓库 (映射…

记录hutool http通过代理模式proxy访问外面的链接

效果&#xff1a; 代码&#xff1a; public class TestMain {public static void main(String[] args){HttpRequest httpRequest HttpRequest.get("https://www.youtube.com").timeout(30000);httpRequest.setProxy(new Proxy(Proxy.Type.HTTP,new InetSocketAddre…