SSE 是指 "Server-Sent Events",即服务器推送事件。它是一种基于 HTTP 的服务器推送技术,允许服务器实时向客户端推送数据。SSE 规范定义了一种在客户端和服务器之间单向实时通信的方式,通常用于实现服务器向客户端推送更新、通知或实时数据。
使用 SSE,客户端可以通过简单的 JavaScript 代码监听来自服务器的事件流,从而实现实时更新,而无需轮询服务器或使用复杂的 WebSocket 协议。SSE 通常用于实现实时性要求不高、但需要实时更新的应用场景,比如股票市场更新、即时通讯等。
SSE 规范定义了一些特定的 HTTP 头部和事件格式,以及客户端和服务器之间的通信方式,从而实现了简单而高效的服务器推送功能。
以下是一个符合 SSE 规范的简单请求示例:
GET /events HTTP/1.1
Host: example.com
Accept: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
在这个示例中,客户端向服务器发送了一个 GET 请求,请求的资源路径是 "/events"。请求头中包含了 "Accept: text/event-stream",表示客户端希最接收服务器推送的事件流。另外,还设置了 "Cache-Control: no-cache" 和 "Connection: keep-alive" 头部,以确保不缓存响应并保持长连接。
服务器在收到这个请求后,可以使用类似下面的响应来向客户端推送事件:
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
data: Hello, world!
data: This is a second message.
在这个响应中,服务器使用 "Content-Type: text/event-stream" 表示响应是一个 SSE 事件流。接着使用 "data" 字段来发送事件数据,每个事件以 "data:" 开头,后面跟着事件的内容。客户端收到这样的响应后,就可以解析其中的事件数据并进行相应的处理。
这就是一个简单的符合 SSE 规范的请求和响应示例。
客户端
在客户端,您可以使用 JavaScript 来处理服务器推送的 SSE 事件流。以下是一个简单的示例代码,演示了如何使用 JavaScript 来接收和处理 SSE 事件流:
const eventSource = new EventSource('/events');
eventSource.onopen = function(event) {
console.log('Connection opened.');
};
eventSource.onmessage = function(event) {
const eventData = JSON.parse(event.data);
console.log('Received event data:', eventData);
// 在这里可以对接收到的事件数据进行处理
};
eventSource.onerror = function(event) {
if (event.eventPhase === EventSource.CLOSED) {
console.log('Connection was closed.');
} else {
console.error('Error occurred:', event);
}
};
在这个示例中,我们首先创建了一个新的 EventSource 对象,指定了服务器端的事件流路径 "/events"。然后我们定义了三个事件处理函数:
- onopen 事件处理函数在连接建立时被调用,这里我们简单地输出一条日志。
- onmessage 事件处理函数在接收到新的事件数据时被调用,我们在这里解析并处理接收到的事件数据。
- onerror 事件处理函数在发生错误时被调用,我们在这里输出错误信息。
通过这些事件处理函数,我们可以实现对服务器推送的事件流的监听和处理。当服务器向客户端推送事件时,onmessage 事件处理函数会被调用,从而实现了实时更新和处理。
服务端
在 Java 中,您可以使用 Servlet 来处理 SSE 请求并向客户端推送事件。以下是一个简单的示例代码,演示了如何在服务端使用 Java Servlet 来处理 SSE 请求并向客户端推送至少两次事件:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class EventSourceServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/event-stream");
response.setCharacterEncoding("UTF-8");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out = response.getWriter();
// 第一次推送事件
out.write("data: First event\n\n");
out.flush();
// 模拟延迟
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 第二次推送事件
out.write("data: Second event\n\n");
out.flush();
}
}
在这个示例中,我们创建了一个名为 EventSourceServlet 的 Servlet 类,覆盖了 doGet 方法来处理 GET 请求。在该方法中,我们首先设置了响应的内容类型为 "text/event-stream",并且禁用了缓存。然后我们获取了输出流,并向客户端推送了两次事件,每次事件之间模拟了一个 2 秒的延迟。
通过这个示例,您可以在 Java 中实现一个简单的 SSE 服务端,并向客户端推送至少两次事件。当客户端发起 GET 请求时,服务器会向客户端推送事件流,客户端可以通过前面提供的 JavaScript 代码来接收和处理这些事件。