EventSource 是一种用于从服务器端接收实时事件的 Web API。它可以向浏览器端发送即时更新的数据,这对于需要实时交互的应用程序非常有用。这篇文章将详细介绍 EventSource 的使用。
基本概念
在理解 EventSource 的使用之前,需要了解几个基本概念。
服务器推送
服务器推送是指服务器将数据或事件实时推送到客户端,而不是等待客户端的请求。这种推送方式可以提高客户端与服务器之间的响应速度和实时性。
SSE
EventSource 使用 Server-Sent Events(简称 SSE)协议与服务器进行通信。SSE 协议是一种单向通信协议,它允许服务器向客户端发送事件。SSE 中的每个事件都包含一个标识符、一个类型和数据字段。
使用方法
创建 EventSource 实例
要使用 EventSource,需要首先创建一个 EventSource 实例:
const eventSource = new EventSource(url);
其中,url
参数是指向 SSE 服务器的 URL。
监听事件
一旦创建了 EventSource 实例,就可以通过 onopen
、onmessage
和 onerror
属性来监听事件。 onopen
事件在和服务器建立 SSE 连接时触发; onmessage
事件在接收到 SSE 事件时触发,可以通过 data
属性获取事件数据; onerror
事件在建立 SSE 连接或接收 SSE 事件时出现错误时触发。
例如,可以这样监听事件:
eventSource.onopen = e => {
console.log('SSE connection opened');
};
eventSource.onmessage = e => {
const data = JSON.parse(e.data);
console.log(`Received ${data.message} from server`);
};
eventSource.onerror = e => {
console.error('SSE connection failed');
};
发送事件
要向客户端发送事件,服务器需要按照 SSE 协议发送数据。可以使用 text/event-stream
MIME 类型和 data
字段来发送数据。
例如,以下是一个简单的 PHP 脚本,用来向客户端发送 SSE 事件:
header("Content-Type: text/event-stream\n\n");
$data = array(
'message' => 'Hello, world!',
'timestamp' => time()
);
echo 'data: ' . json_encode($data) . "\n\n";
在这个脚本中,header()
函数设置了 MIME 类型为 text/event-stream
,并且发送了一个包含数据的 SSE 事件。
关闭连接
使用 close()
方法可以关闭 SSE 连接:
eventSource.close();
示例
以下是一个简单的例子,演示了如何使用 EventSource 实现实时计时器。这个计时器将在客户端每秒更新一次。
HTML
<!DOCTYPE html>
<html>
<head>
<title>Real-time Timer</title>
</head>
<body>
<h1 id="timer">00:00:00</h1>
<script src="app.js"></script>
</body>
</html>
JavaScript
const eventSource = new EventSource('timer.php');
eventSource.onopen = e => {
console.log('SSE connection opened');
};
eventSource.onmessage = e => {
const data = JSON.parse(e.data);
const timerElement = document.getElementById('timer');
const minutes = Math.floor(data.seconds / 60);
const seconds = data.seconds % 60;
const hours = Math.floor(minutes / 60);
const formattedTime = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
timerElement.textContent = formattedTime;
};
eventSource.onerror = e => {
console.error('SSE connection failed');
};
PHP
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$time = time() - $_SERVER['REQUEST_TIME'];
while (1) {
$data = array(
'seconds' => $time
);
$event = 'data: ' . json_encode($data) . "\n\n";
echo $event;
ob_flush();
flush();
sleep(1);
$time++;
}
在这个例子中,客户端每秒钟会从服务器端接收到 SSE 事件,其中包含了已经过去的秒数。客户端将秒数转换为格式化的时间字符串,然后将其显示在页面上。
总结
EventSource 是一个非常有用的 Web API,可以让服务器和客户端直接进行实时通信。使用 EventSource 可以大大提高应用程序的实时性和动态性。