Sever-Sent Events(SSE) 服务器向 Web 客户端推送实战示例

概念

Sever-Sent Events(SSE) 可实现由服务端主动推送消息给客户端

特点:

  • 基于 HTTP 协议
  • 由服务端向客户端发送消息,只能单向发送
  • 只支持文本消息
  • 当不通过 HTTP / 2 使用时,SSE会受到最大连接数的限制(Chrome、Firefox 每个浏览器最多 6 个连接)

事件流格式

事件流仅仅是一个简单的文本数据流,文本应使用 UTF-8 格式编码。
每条消息后面都由一个空行作为分隔符。

  • 例 1:客户端将收到 myevent 事件类型,消息为 xxxx\nyyyy

event: myevent
data: xxxx
data: yyyy

  • 例 2:未指定事件类型,默认为 message 事件类型,消息为 zzzz

data: zzzz

  • 例 3:冒号开头,表示注释,可以用来防止连接超时,服务器可以定期发送一条消息注释行,以保持连接不断。

: this is just a annotation

实战 Demo

  • 效果图

Server-Sents Events

  • Web 客户端
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>SSE Demo</title>
</head>
<body>
    <div id="messages"></div>
    <script>
        const source = new EventSource('sse.php');

        // 建立连接
        source.onopen = function () {
            var messages = document.getElementById('messages');
            messages.innerHTML += 'connection is established' + '<br>';
        };

        // ping 事件类型消息
        source.addEventListener("ping", function(event) {
            var messages = document.getElementById('messages');
            messages.innerHTML += 'ping: ' + event.data + '<br>';
        });

        // message 事件类型消息
        source.onmessage = function(event) {
            var messages = document.getElementById('messages');
            messages.innerHTML += event.data + '<br>';
        };

        // 连接错误
	    source.onerror = function (event) {
	        var messages = document.getElementById('messages');
	        var data = 'connection state: ' + eventSource.readyState + ', error: ' + event
            messages.innerHTML += data + '<br>';
	    };
    </script>
</body>
</html>
  • 服务端
<?php

// 禁用缓存
header("Cache-Control: no-cache");
// 指明 MIMI
header("Content-Type: text/event-stream");
// 使用持久连接
header('Connection: keep-alive');


while (true) {
  // 发送 ping 事件类型消息
  echo "event: ping\n";
  echo 'data: {"time": "' . date('Y-m-d H:i:s'). '"}';
  echo "\n\n";


  if (time() % 5 === 0) {
    // 未指定事件类型,默认为 message 事件类型
    echo 'data: This is a message at time ' . date('Y-m-d H:i:s') . "\n\n";
  }

  ob_end_flush();
  flush();
  sleep(1);
}

参考

  • https://developer.mozilla.org/zh-CN/docs/Web/API/Server-sent_events
  • https://zhuanlan.zhihu.com/p/444011262
  • https://github.red/talking-about-eventstream/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈挨踢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值