HTML Server-Sent 事件(Server-Sent Events)是一种用于在客户端和服务器之间建立持久连接的技术,它允许服务器向客户端发送实时的事件流。Server-Sent 事件提供了一种简单而有效的机制,用于实时地向客户端推送数据。
一、Server-Sent事件示例
以下是一个示例,展示了如何在客户端使用 Server-Sent 事件:
<!DOCTYPE html> <html> <head> <title>Server-Sent Events Example</title> </head> <body> <h1>Server-Sent Events Example</h1> <div id="message-container"></div> <script> // 创建 EventSource 对象,指定服务器端事件流的 URL var eventSource = new EventSource('/event-stream'); // 监听服务器端发送的消息事件 eventSource.addEventListener('message', function(event) { var messageContainer = document.getElementById('message-container'); // 将服务器发送的消息添加到页面中 messageContainer.innerHTML += event.data + '<br>'; }); </script> </body> </html>
在服务器端,你需要设置一个路由来处理客户端的 EventSource 请求,并发送事件流给客户端。具体的实现方式取决于你使用的后端技术,例如 Node.js、PHP 或者 Java 等。
以下是一个伪代码示例,演示了如何在 Node.js 使用 Express 框架来处理 EventSource 请求:
const express = require('express'); const app = express(); // 设置路由,处理客户端的 EventSource 请求 app.get('/event-stream', (req, res) => { // 设置响应头,指定事件流的 MIME 类型和编码 res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); // 发送事件流给客户端 setInterval(() => { res.write('data: Hello from server\n\n'); }, 1000); }); app.listen(3000, () => { console.log('Server listening on port 3000'); });
在上面的示例中,服务器每隔一秒发送一个包含 “Hello from server” 的事件给客户端。客户端通过监听 ‘message’ 事件,将接收到的消息显示在页面上。
二、接收Server-Sent事件通知
EventSource 对象用于接收服务器发送事件通知:
var source = new EventSource("demo_sse.php"); source.onmessage = function(event) { document.getElementById("result").innerHTML += event.data + "<br>"; };
- 创建一个新的 EventSource 对象,然后规定发送更新的页面的 URL(本例中是 “demo_sse.php”);
- 每当接收到一次更新,就会发生 onmessage 事件;
- 当 onmessage 事件发生时,把已接收的数据推入 id 为 “result” 的元素中。
三、检测Server-Sent事件支持
在 TIY 实例中,我们编写了一段额外的代码来检测服务器发送事件的浏览器支持:
if(typeof(EventSource) !== "undefined") { // 是的!支持服务器发送事件! // 一些代码..... } else { // 抱歉!不支持服务器发送事件! }
四、服务器端代码实例
为了使上例运行,您需要能够发送数据更新的服务器(比如 PHP 或 ASP)。
服务器端事件流的语法非常简单。请把 “Content-Type” 报头设置为 “text/event-stream”。现在,您可以开始发送事件流了。
1、PHP 中的代码 (demo_sse.php):
<?php header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); $time = date('r'); echo "data: The server time is: {$time}\n\n"; flush(); ?>
在 PHP 中,通过设置报头 “Content-Type” 为 “text/event-stream” 和 “Cache-Control” 为 “no-cache”,服务器告诉浏览器它将发送一个事件流,并禁用缓存。然后使用 echo 输出带有 “data: ” 前缀的数据,并调用 flush() 来立即发送给客户端。
2、ASP 中的代码 (VB) (demo_sse.asp):
<% Response.ContentType = "text/event-stream" Response.Expires = -1 Response.Write("data: The server time is: " & now()) Response.Flush() %>
在 ASP 中,通过设置 ContentType 为 “text/event-stream” 和 Expires 为 -1,服务器同样告知浏览器将发送一个事件流,并不对页面进行缓存。然后使用 Response.Write 输出带有 “data: ” 前缀的数据,并调用 Response.Flush() 来立即发送给客户端。
五、EventSource对象
除了使用 onmessage 事件来接收消息外,还可以使用其他事件来处理 Server-Sent 事件。
1、onopen 事件:当与服务器的连接成功建立时触发。可以在这个事件中执行一些初始化操作,比如显示连接成功的提示信息。
示例代码:
eventSource.onopen = function(event) { console.log("Connection to server opened"); };
2、onmessage 事件:当接收到服务器发送的消息时触发。可以在这个事件中处理接收到的消息数据。
eventSource.onmessage = function(event) { var data = event.data; console.log("Received message: " + data); };
3、onerror 事件:当发生错误时触发,例如无法连接到服务器或服务器断开连接。可以在这个事件中处理错误情况,并进行相应的提示或重连操作。
eventSource.onerror = function(event) { console.error("An error occurred: " + event.target.readyState); };
六、浏览器支持
下面表格中的数字指示完全支持 server-sent 事件的首个浏览器:
浏览器 | IE | Firefox | Safari | Opera | |
版本 | 6.0 | 不支持 | 6.0 | 5.0 | 11.5 |