laravel+sse实现实时推送

sse简介

Server-Sent Events(SSE)是一种用于实现服务器向客户端实时推送数据的Web技术。与传统的轮询和长轮询相比,SSE提供了更高效和实时的数据推送机制。

SSE基于HTTP协议,允许服务器将数据以事件流(Event Stream)的形式发送给客户端。客户端通过建立持久的HTTP连接,并监听事件流,可以实时接收服务器推送的数据。

SSE的主要特点包括:
 1. 简单易用:SSE使用基于文本的数据格式,如纯文本、JSON等,使得数据的发送和解析都相对简单。 
 2. 单向通信:SSE支持服务器向客户端的单向通信,服务器可以主动推送数据给客户端,而客户端只能接收数据。
 3. 实时性:SSE建立长时间的连接,使得服务器可以实时地将数据推送给客户端,而无需客户端频繁地发起请求。

代码块

laravel后端

php 复制代码
	/**
     * 消息推送-sse-实时推送
     */
    public function realTimeMessagePush(Request $request){
        $userId = $request->get("userId")??0; # 因多个用户,向指定用户推送

        ob_end_clean(); #函数清除,该函数清除php缓冲区内的内容,并且关闭输出缓冲区
        $response =  response()->stream(function () use ($userId){
            while (true) {
                #推送缓存
                # 将数据存储到redis-list中,缓存10秒,实现当用户在线时推送,不在线不推送
                $messageRedis = Redis::lpop("mailMessage:".$userId);
                if ($messageRedis){
                    $messageRedis = json_decode($messageRedis,true);
                    if (isset($userId) && $userId == $messageRedis['to_id']){
                        #echo "retry: 2000\n";#失败重连(毫秒)
                        echo 'data: '.json_encode($messageRedis)."\n";
                        echo "\n";
                    }
                }
                
                if(ob_get_level()>0){
                    ob_flush();
                }
                flush();
                if (connection_aborted()) {break;}
                sleep(2); # 2秒推送一次
            }
        }, 200, [
            'Cache-Control' => 'no-cache',
            'X-Accel-Buffering' => 'no',
            'Content-Type' => 'text/event-stream',
        ]);
        return $response;
    }

前端代码

弹出页面消息,3秒后消失
html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>SSE Example</title>
    <style>
        .notification-container {
            position: fixed;
            top: 10px;
            right: 10px;
            max-width: 300px;
            width: 100%;
        }

        .notification {
            padding: 10px;
            background-color: #f0f0f0;
            border: 1px solid #ccc;
            border-radius: 5px;
            opacity: 0;
            transform: translateX(100%);
            transition: transform 0.5s, opacity 0.5s;
            animation: slide-in 0.5s forwards;
        }

        .show {
            opacity: 1;
            transform: translateX(0);
        }
    </style>
</head>
<body>
<input type="text" id="userId" value="{{$userId}}">
<div id="sse-output"></div>

<div class="notification-container" id="notification-container">
</div>

<script>
	//页面动画
    var notificationContainer = document.getElementById('notification-container');

    function showNotification(message) {
        var notification = document.createElement("div");
        notification.classList.add("notification", "show");
        notification.textContent = message;
        notificationContainer.appendChild(notification);

        setTimeout(function() {
            notification.style.transition = "transform 0.5s, opacity 0.5s";
            notification.style.transform = "translateX(100%)";
            notification.style.opacity = "0";
            setTimeout(function() {
                notification.remove();
            }, 500);
        }, 3000); // 3秒后自动关闭
    }
	
	//sse使用
    const userId = document.getElementById('userId').value;
	//EventSource 不允许传header头部,并且只能用get请求
    const eventSource = new EventSource('/realTimeMessagePush?userId='+userId);
    
    //eventSource.onopen = function(data){
    //    console.log("连接成功")
    //}
    eventSource.onmessage = function(event) {
        const data = JSON.parse(event.data);
        console.log('Received message:', data);
        // 在此处执行你的前端操作,比如更新页面元素
        showNotification(data.title)
    };
    //eventSource.onerror = function(event) {
    //    console.error('Error occurred:', event);
    //   eventSource.close();
    //};
</script>
</body>
</html>

效果展示

laravel+sse

相关推荐
生椰拿铁You10 分钟前
解决Apache/2.4.39 (Win64) PHP/7.2.18 Server at localhost Port 80问题
php
索然无味io5 小时前
跨站请求伪造之基本介绍
前端·笔记·学习·web安全·网络安全·php
伟大无须多言6 小时前
企业资源规划系统(ERP)服务器上线项目实施指南
开发语言·php
网络安全(king)6 小时前
网络安全设备
网络·web安全·php
蜗牛hb10 小时前
VMware Workstation虚拟机网络模式
开发语言·学习·php
手可摘星河11 小时前
php中 cli和cgi的区别
开发语言·php
EasyDSS12 小时前
国标GB28181-2022平台EasyGBS:安防监控中P2P的穿透方法
网络协议·php·音视频·p2p
liuyunshengsir13 小时前
Squid代理服务器的安装使用
开发语言·php
007php0071 天前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
卜及中1 天前
【Linux】资源隔离机制 — 命名空间(Namespace)详解
linux·服务器·php