跳转到主要内容

category

介绍


服务器发送事件(SSE)是一种允许服务器实时向客户端推送更新的技术。这对于需要实时通信的应用程序非常有用,例如实时通知、聊天应用程序和股票行情器。在本文中,我们将探讨如何使用流行的基于Java的框架Spring来实现SSE。

先决条件:

 

  • 对Java和Spring框架的基本理解
  • Java开发环境(JDK 8或更高版本)和文本编辑器或IDE
  • Gradle或Maven用于依赖关系管理

步骤1:设置项目


首先,让我们创建一个新的Spring Boot项目。您可以使用Spring Initializer生成具有以下依赖项的基本项目:

  • Web(用于构建Web应用程序)
  • Lombok (减少样板代码)


步骤2:添加必要的依赖项


将以下依赖项添加到build.gradle或pom.xml中:

Gradle:

implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.projectlombok:lombok'

Maven:

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
</dependencies>


步骤3:创建SSE控制器


现在,让我们创建一个简单的SSE控制器。此控制器将公开客户端可以连接到的端点,以便接收实时更新。

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

@RestController
public class SseController {

@GetMapping(path = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter subscribe() {
SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
// Add the emitter to a list of subscribers or handle it in another way
return emitter;
}
}


步骤4:向客户端发送事件


要将事件发送到客户端,您需要一个方法来遍历所有活动的发射器并发送数据。对于本例,我们将创建一个简单的服务,该服务定期向所有连接的客户端发送时间戳。

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

@Service
public class SseService {

    private final List<SseEmitter> emitters = new CopyOnWriteArrayList<>();

    public void addEmitter(SseEmitter emitter) {
        emitters.add(emitter);
        emitter.onCompletion(() -> emitters.remove(emitter));
        emitter.onTimeout(() -> emitters.remove(emitter));
    }

    @Scheduled(fixedRate = 1000)
    public void sendEvents() {
        for (SseEmitter emitter : emitters) {
            try {
                emitter.send(System.currentTimeMillis());
            } catch (IOException e) {
                emitter.complete();
                emitters.remove(emitter);
            }
        }
    }
}

 


不要忘记在您的Spring Boot应用程序中启用调度:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class SseDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SseDemoApplication.class, args);
    }
}


步骤5:连接客户端


现在我们已经准备好了服务器端实现,我们可以创建一个简单的HTML页面来连接到SSE端点并显示事件。

在src/main/resources/static文件夹中创建一个index.html文件,其中包含以下内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Spring SSE Demo</title>
</head>
<body>
    <h1>Server-Sent Events (SSE) with Spring</h1>
    <div id="events"></div>

    <script>
        const eventSource = new EventSource("/sse");

        eventSource.onmessage = (event) => {
            const div = document.createElement("div");
            div.textContent = `Event received: ${event.data}`;
            document.getElementById("events").appendChild(div);
        };

        eventSource.onerror = (error) => {
            console.error("Error occurred:", error);
            eventSource.close();
        };
    </script>
</body>
</html>

 

步骤6:运行并测试应用程序


您现在可以运行应用程序了。在您的终端中,执行以下命令:
./gradlew bootRun

./mvnw spring-boot:run
现在,打开浏览器并导航到http://localhost:8080.您应该可以看到实时接收和显示的事件。

结论


我们已经使用Spring框架成功地实现了服务器发送事件(SSE)。这是实现服务器和客户端之间实时通信的强大方法。请记住,SSE只是可用于实时通信的众多技术之一,您应该为您的特定用例选择最佳选项。其他替代方案包括WebSockets和Long Polling。

标签