使用swoole实现实时消息推送给客户端

news2024/11/26 9:39:20

一. 测试服务端

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【操作系统】虚拟内存相关分段分页页面置换算法

虚拟内存是什么&#xff1f; 【进程地址空间虚拟地址空间C/C程序地址空间就是那个4G的空间】 虚拟内存是操作系统内核为了对进程地址空间进行管理&#xff0c;而设计的一个逻辑意义上的内存空间概念。在程序运行过程中&#xff0c;虚拟内存中需要被访问的部分会被映射到物理内…

Mock平台-08开发:项目管理(四)编辑功能和Component抽离

【Mock平台】为系列测试开发教程&#xff0c;从0到1编码带你一步步使用Spring Boot 和 Antd React框架完成搭建一个测试工具平台&#xff0c;希望作为一个实战项目对各位的测试开发学习之路有帮助&#xff0c;大奇一个专注测试技术干货原创与分享的家伙。 本篇重点&#xff1a;…

HCIP生成树STP总结

STP生成树 网桥的4个选举 根网桥&#xff1a; 有且仅有一台&#xff0c;且由BPDU中的桥ID来决定 桥ID 网桥优先级&#xff08;0-65535公有&#xff09; 默认32768 MAC地址&#xff08;只有…

湘潭大学 湘大 XTU OJ 1055 整数分类 题解(非常详细)

链接 整数分类 题目 Description 按照下面方法对整数x进行分类&#xff1a;如果x是一个个位数&#xff0c;则x属于x类&#xff1b;否则将x的各位上的数码累加&#xff0c;得到一个新的x&#xff0c;依次迭代&#xff0c;可以得到x的所属类。比如说24&#xff0c;246&#…

漏洞指北-VulFocus靶场专栏-高级01

漏洞指北-VulFocus靶场专栏-高级01 高级001 &#x1f338;骑士cms任意代码执行&#xff08;CVE-2020-35339&#xff09;&#x1f338;step1&#xff1a;进入页面&#xff0c;登入后台step2 系统——网站配置——网站域名step3 中国蚁剑连接 高级002 &#x1f338;Django SQL注入…

安装ps找不到vcruntime140_1.dll怎么回事?有哪些解决方法

安装ps找不到vcruntime140_1.dll怎么回事&#xff1f;这可能是因为您的计算机Visual C Redistributable包损坏&#xff0c;其中包含vcruntime140_1.dll文件。VCRuntime140_1.dll是一个重要的动态链接库文件&#xff0c;它包含了Visual C运行时所需的一些函数和资源。当这个文件…

银行客户关系管理系统springboot财务金融进销存java jsp源代码

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 银行客户关系管理系统springboot 系统有1权限&#x…

周易卦爻解读笔记——未济

第六十四卦未济 火水未济 离上坎下 未济卦由否卦所变&#xff0c;否卦六二与九五换位&#xff0c;象征尚未完成。 天地否 未济卦和既济卦既是错卦又是覆卦&#xff0c;这也是最后一卦&#xff0c;序卦传【物不可穷也&#xff0c;故受之以未济终焉】 未济卦象征尚未完成&…

NSSCTF之Misc篇刷题记录(14)

[SWPUCTF] 2021新生赛之Crypto篇刷题记录① [UUCTF 2022 新生赛]王八快跑[安洵杯 2020]BeCare4[HDCTF 2023]ExtremeMisc NSSCTF平台&#xff1a;https://www.nssctf.cn/ PS&#xff1a;记得所有的flag都改为NSSCTF [UUCTF 2022 新生赛]王八快跑 小游戏 小乌龟跑过线就有 fla…

BDA初级分析——SQL语句应用基础练习题

1、请检查OLYMPIC表中是否存在重复国家? SELECT Team,COUNT(*) AS 重复次数 FROM Olympic GROUP BY Team HAVING COUNT(*) > 1;SELECT COUNT(Team),COUNT(DISTINCT(Team)) FROM Olympic; 2、将OLYMPIC表中Armenia(ARM)的奖牌总数更新为14 UPDATE Olympic SET total_medals …

【C语言】使用C语言,实现九九乘法表(另附Python、Java、JavaScript实现方式)

文章目录 1. C语言实现1.1 思路1.2 代码实现 3.其他语言实现3.1 Python实现3.2 Java实现3.3 JavaScript实现 1. C语言实现 1.1 思路 九九乘法表图示&#xff1a; 思路如下&#xff1a;定义两层for循环即可实现九九乘法表 一共有9层&#xff0c;所以要定义一个变量i&#xff…

记录首次面试2023-08-18

人生第一次面试&#xff0c;大概一个小时左右。没有问我C的&#xff0c;上来一个数据库事务&#xff0c;虽然没有复习&#xff0c;但是还是能够记住一些&#xff0c;主要问的一些事务的隔离级别&#xff0c;以及都有什么作用&#xff0c;我是举例回答的&#xff0c;客户端A和客…

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

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

PCAP01介绍和STM32模拟SPI驱动

一.芯片介绍 Pcap01是德国acam公司设计的一款革命性的电容测量芯片。该芯片 内部有DSP计算单元&#xff0c;可以直接将电容元件接到Pcap01芯片&#xff0c;然后芯片计算出容值大小&#xff0c;通过SPI总线将电容容值数据传送给CPU&#xff0c;电容测量完全数字化。 二,测量原…

不要着急购买iPhone 15,先看看这5点再做决定吧!

人们对下个月可能推出的iPhone 15感到兴奋,这是有充分理由的——有传言称,新机型正在做出一些重大改变,尤其是在iPhone 15 Pro机型方面。从四款新iPhone都采用USB-C,到iPhone 15 Pro Max采用潜望镜式长焦镜头以实现更好的变焦,听起来有很多功能值得兴奋。 当然,除非你没…

软件综合测试实训室建设方案

一、实训室总体目标 培养目标:培养软件测试的专业技术人才,使学生掌握软件测试的基本理论知识,熟练运用各类测试工具,具备随产品版本迭代进行回归测试的能力。 建设目标:打造一流的软件测试培训基地,建成集教学实训、技术研发、项目实习为一体的软件测试人才培养高地。 二、…

文件上传xxx

本地保存文件 将文件保存到服务器本地硬盘中 max-request-size 多个文件总大小不能大于100M PostMapping("/upload")public Result upload(String username,Integer age,MultipartFile image) throws IOException {log.info("用户名:{},牛叔&#xff1a;{},文件…

Android 多渠道打包及VasDolly使用

目录 1.添加productFlavors的配置buildConfigFieldmanifestPlaceholdersresValue 2.设置apk文件的名称&#xff0c;便于识别3.添加vasdolly、添加gradle脚本&#xff08;windows&#xff09; 作用&#xff1a;一次性可以打多个apk包&#xff0c;名字、包名、logo等可以不相同。…

掌控未知:项目中如何巧妙应对突发与紧急

引言 在项目管理的领域中&#xff0c;每一个项目都伴随着一系列的不确定性和挑战。这些不确定性可能源于外部环境的变化、团队内部的动态或技术的快速迭代。而在这些不确定性中&#xff0c;突发和紧急事件尤为考验项目经理的应变能力和决策智慧。那么&#xff0c;如何在项目中…

【排排站:探索数据结构中的队列奇象】

本章重点 队列的概念及结构 队列的实现方式 链表方式实现栈接口 队列面试题 一、队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out) 入队列&#x…