Java Web 中的 Server-Sent Events (SSE) 入门介绍

Java Web 中的 Server-Sent Events (SSE) 入门介绍

Server-Sent Events(服务器发送事件,简称 SSE) 是一种用于实现服务器向客户端推送实时更新的技术。与 WebSocket 不同,SSE 是一种单向通信技术,适用于只需要从服务器到客户端的数据流场景。

1. 基本概念

  • SSE 的特点

    • 单向通信:数据只能从服务器发送到客户端。
    • 长连接:客户端与服务器保持一个长时间的 HTTP 连接。
    • 自动重连:如果连接断开,客户端会自动尝试重新连接。
  • 适用场景

    • 实时股票价格更新
    • 实时聊天系统(仅显示消息)
    • 通知推送

2. SSE 的基本原理

SSE 的实现基于 HTTP 协议。客户端通过 JavaScript 的 EventSource 对象向服务器发起一个长连接请求。服务器可以通过这个连接源源不断地向客户端发送事件数据。

  • 客户端代码示例

    const eventSource = new EventSource('http://example.com/sse-endpoint');
    
    eventSource.addEventListener('message', function(event) {
        console.log('收到消息:', event.data);
    });
    
  • 服务器端代码(Java)

    • 服务器需要通过 HTTP 响应流发送事件数据,格式为 text/event-stream

3. Java Web 中实现 SSE

3.1 配置 Maven 依赖

如果你使用 Maven 管理项目依赖,确保你的 pom.xml 包含以下内容(如果是 Spring Boot 项目,通常已经包含相关依赖):

<dependencies>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
dependencies>
3.2 创建一个 SSE 控制器

在 Spring Boot 中,可以通过创建一个控制器来处理 SSE 请求。

import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Controller
public class SSEController {

    @GetMapping("/sse")
    public StreamingResponseBody sse() {
        return outputStream -> {
            try {
                // 发送事件数据,格式为 "data: \n\n"
                while (true) {
                    String message = "服务器时间:" + System.currentTimeMillis();
                    String eventLine = "data: " + message + "\n\n";
                    outputStream.write(eventLine.getBytes());
                    outputStream.flush();
                    
                    TimeUnit.SECONDS.sleep(1);
                }
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        };
    }
}
3.3 配置响应头

在 SSE 的实现中,需要设置以下 HTTP 响应头:

  • Content-Type: text/event-stream:指定响应内容类型为事件流。
  • Cache-Control: no-cache:防止浏览器缓存响应。

如果你使用 Spring Boot,可以在控制器方法上添加注解或自定义配置来设置这些响应头。例如:

@GetMapping(value = "/sse", produces = "text/event-stream")
@ResponseBody
public StreamingResponseBody sse() {
    // 实现逻辑
}

4. 客户端代码示例

在前端,通过 EventSource 对象订阅 SSE 数据。

DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>SSE 示例title>
head>
<body>
    <div id="messages">div>

    <script>
        const eventSource = new EventSource('http://localhost:8080/sse');
        
        eventSource.addEventListener('message', function(event) {
            const messagesDiv = document.getElementById('messages');
            const message = document.createElement('div');
            message.textContent = event.data;
            messagesDiv.appendChild(message);
        });

        // 处理错误
        eventSource.onerror = function(err) {
            console.error('SSE 连接错误:', err);
        };
    script>
body>
html>

5. SSE 的优缺点

优点:
  • 实现简单,基于 HTTP 协议。
  • 客户端自动重连断开的连接。
  • 流量较小,适合单向数据流场景。
缺点:
  • 只支持单向通信。
  • 不适用于需要双向通信的场景(如实时聊天)。
  • 对浏览器的支持依赖于 EventSource 接口。

6. 注意事项

  • 长连接问题:SSE 需要保持一个长时间的 HTTP 连接,服务器和客户端都需要处理超时、断开等问题。
  • 服务器资源占用:每个 SSE 连接都会占用一定的服务器资源,需要注意并发连接数的问题。
  • 浏览器限制:某些浏览器对 EventSource 的支持有限,需要确保目标用户使用的浏览器是兼容的。

7. 总结

通过 SSE 技术,可以在 Java Web 应用中轻松实现服务器向客户端推送实时数据的功能。SSE 的实现简单且高效,特别适用于单向数据流场景。如果你需要更复杂的双向通信功能,则可以考虑使用 WebSocket。

希望以上内容对你理解 Java Web 中的 SSE 实现有帮助!

你可能感兴趣的:(前端,java,前端,开发语言)