• laravel+sse实现实时推送


    sse简介

    Server-Sent Events(SSE)是一种用于实现服务器向客户端实时推送数据的Web技术。与传统的轮询和长轮询相比,SSE提供了更高效和实时的数据推送机制。
    
    SSE基于HTTP协议,允许服务器将数据以事件流(Event Stream)的形式发送给客户端。客户端通过建立持久的HTTP连接,并监听事件流,可以实时接收服务器推送的数据。
    
    SSE的主要特点包括:
     1. 简单易用:SSE使用基于文本的数据格式,如纯文本、JSON等,使得数据的发送和解析都相对简单。 
     2. 单向通信:SSE支持服务器向客户端的单向通信,服务器可以主动推送数据给客户端,而客户端只能接收数据。
     3. 实时性:SSE建立长时间的连接,使得服务器可以实时地将数据推送给客户端,而无需客户端频繁地发起请求。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    代码块

    laravel后端

    	/**
         * 消息推送-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;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    前端代码

    弹出页面消息,3秒后消失
    
    • 1
    DOCTYPE html>
    <html>
    <head>
        <title>SSE Exampletitle>
        <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    效果展示

    laravel+sse

  • 相关阅读:
    pip安装skimage的方法
    kafka rabbitmq 详细对比
    ISO Swift高德导航开发指南
    OAuth 2.1 框架
    docker容器操作
    xss漏洞简单案例
    收集文档1
    暂存6暂存6暂存6
    PAT 1027 Colors in Mars
    【python核心】函数式编程(二)
  • 原文地址:https://blog.csdn.net/Tiramisu_5/article/details/133806530