Java使用Server-Sent Events (SSE) 的demo

SSE类似于HTTP,客户端通过请求向客户端注册SSE的请求,new SseEmitter()则代表请求成功,可以通过SseEmitter.event().data("连接成功")向浏览器指定的event(默认为data)发送信息。

 

java

@GetMapping(path = "/subscribe/{id}")
public SseEmitter subscribe(@PathVariable("id") String id) throws IOException {
    if (StringUtil.isEmpty(id)) {
        return null;
    }
    SseEmitter sseEmitter;
    SseEmitter getClientEmitter = sseCache.get(id);
    if (getClientEmitter == null || !checkSseConnectAlive(getClientEmitter)) {
        // 持久生存
        sseEmitter = new SseEmitter(0L);
        // 设置前端的重试时间
        try {
            sseEmitter.send(SseEmitter.event().data("连接成功"));
            sseCache.put(id, sseEmitter);
            System.out.println("add " + id);
            sseEmitter.onTimeout(() -> {
                System.out.println(id + "超时");
                sseCache.remove(id);
            });
            sseEmitter.onCompletion(() -> System.out.println("已关闭连接:" + id));
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    } else {
        System.out.println("已存在!");
        sseEmitter = getClientEmitter;
    }
    return sseEmitter;
}

在这个例子中,首先我们定义了一个名为/subscribe的URL,当客户端访问这个URL时,服务器会返回一个新的SseEmitter对象。

SSE的优点不仅在于其简单易用和实时性,还体现在其可靠性上。如果网络中断,SSE会自动尝试重新连接。一旦连接恢复,服务器就可以继续向客户端发送更新。

然而,SSE也有一些缺点需要注意。首先是浏览器兼容性问题,尽管大多数现代浏览器都支持SSE,但是一些旧版本的浏览器,如IE9及更早版本,不支持此功能。其次,由于SSE需要保持长连接,这可能会消耗大量的服务器资源,特别是在高并发情况下。

总的来说,Server-Sent Events是一种强大而实用的实现实时通信的技术。如果你正在开发需要实时更新的应用程序,并且对浏览器兼容性和服务器资源有一定的控制能力,那么SSE绝对值得你考虑。

协议方式HTTP SSEWebSocket
通信方式

单向通信

浏览器 → 服务器

单向通信

浏览器 ← 服务器

双向通信

浏览器 ↔服务器

长连接
实时性

适用场景浏览器请求,加载网页,提交数据推送消息,消息提醒,时间推送网络聊天

Server-Sent Events (SSE) 和 HTTP 是两种不同的通信协议,它们在实现客户端和服务器之间的数据传输时有各自的优点和适用场景。下面是 SSE 和 HTTP 的一些对比:

HTTP

  1. 单向通信:HTTP 是一种单向请求-响应协议。客户端发起一个请求,服务器响应这个请求,然后连接关闭。
  2. 非持久性连接:每次请求结束后,HTTP 连接都会被关闭。如果需要连续更新,客户端需要不断发起新的请求。
  3. 实时性较差:由于 HTTP 需要客户端轮询服务器以获取更新,这使得其不适合实时性要求较高的应用。

Server-Sent Events (SSE)

  1. 双向通信:SSE 允许服务器主动将数据推送到客户端,而不仅仅是响应客户端的请求。
  2. 持久性连接:一旦建立 SSE 连接,它会保持打开状态,直到客户端或服务器选择断开连接。
  3. 实时性强:由于服务器可以主动推送更新,SSE 适合实时性要求较高的应用,如股票报价、聊天应用等。

比较与总结

  • HTTP 更适用于一次性请求和响应的情况,例如加载网页内容或提交表单数据。
  • SSE 更适用于需要持续更新的应用,比如新闻流、聊天室或者动态图表的数据更新。

然而,这两种协议并不是互斥的。实际上,在许多情况下,它们会被结合使用,以便充分利用各自的优势。例如,一个应用程序可能会用 HTTP 来加载初始页面,然后用 SSE 来提供实时更新。

在Tomcat中配置了一个连接超时时间connectionTimout,如果在这个时间之后客户端不还未得到服务器端的响应,就会主动断开连接,产生上述异常,Tomcat中默认超时时间是20秒,我们一般设置为60秒,从而避免后台程序处理时间太长导致断开连接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个基于Spring Boot的Server-Sent Events示例: 首先,在pom.xml文件中添加以下依赖项: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 接下来,创建一个名为“ServerSentEventController”的新类,该类将处理Server-Sent Events请求: ``` import java.time.LocalTime; 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 ServerSentEventController { @GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public SseEmitter serverSentEvent() { SseEmitter emitter = new SseEmitter(); LocalTime currentTime = LocalTime.now(); // 发送当前时间 emitter.send(SseEmitter.event().data("Current time: " + currentTime.toString())); // 定时发送时间 Thread thread = new Thread(() -> { try { while (true) { Thread.sleep(5000); currentTime = LocalTime.now(); emitter.send(SseEmitter.event().data("Current time: " + currentTime.toString())); } } catch (Exception e) { emitter.complete(); } }); thread.start(); return emitter; } } ``` 在上面的代码中,我们创建了一个名为“serverSentEvent”的控制器方法,该方法返回一个SseEmitter对象,该对象将用于发送Server-Sent Events。在这个方法中,我们首先发送当前时间,然后设置一个线程,每隔5秒发送一次当前时间,直到连接关闭或发生异常为止。 最后,在Spring Boot应用程序的主类上添加@EnableWebMvc注释: ``` import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @SpringBootApplication @EnableWebMvc public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 现在,您可以启动应用程序并访问“http://localhost:8080/sse”来查看Server-Sent Events的示例。您应该能够在浏览器中看到当前时间,并且每隔5秒钟更新一次。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值