• springboot使用SSE


    1、pom文件 

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-webartifactId>
    4. dependency>

    2、前端代码

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title> Springboot集成SSE title>
    6. head>
    7. <script>
    8. let source = null;
    9. const clientId = new Date().getTime();
    10. if (!!window.EventSource) {
    11. source = new EventSource('http://127.0.0.1:8080/sse/subscribe?id=' + clientId);
    12. //建立连接
    13. source.onopen = function (event) {
    14. setMessageInnerHTML("建立连接" + event);
    15. }
    16. //接收数据
    17. source.onmessage = function (event) {
    18. setMessageInnerHTML(event.data);
    19. }
    20. //错误监听
    21. source.onerror = function (event) {
    22. if (event.readyState === EventSource.CLOSED) {
    23. setMessageInnerHTML("连接关闭");
    24. } else {
    25. console.log(event);
    26. }
    27. }
    28. } else {
    29. setMessageInnerHTML("浏览器不支持SSE");
    30. }
    31. window.onbeforeunload = function () {
    32. close();
    33. };
    34. // 关闭
    35. function close() {
    36. source.close();
    37. const httpRequest = new XMLHttpRequest();
    38. httpRequest.open('GET', '/sse/over/?clientId=' + clientId, true);
    39. httpRequest.send();
    40. console.log("close");
    41. }
    42. // 显示消息
    43. function setMessageInnerHTML(innerHTML) {
    44. document.getElementById('text').innerHTML += innerHTML + '
      '
      ;
    45. }
    46. script>
    47. <body>
    48. <button onclick="close()">关闭连接button>
    49. <div id="text">div>
    50. body>
    51. html>

    3、后端代码

    1、订阅
    1. private static Map cache = new ConcurrentHashMap<>();
    2. @GetMapping(path = "subscribe", produces = {MediaType.TEXT_EVENT_STREAM_VALUE})
    3. public SseEmitter subscribe(@RequestParam(name = "id", required = false) String id) throws IOException {
    4. // 超时时间设置
    5. SseEmitter sseEmitter = new SseEmitter(0L);
    6. cache.put(id, sseEmitter);
    7. //结束连接
    8. sseEmitter.onCompletion(() -> {
    9. log.info("结束连接:{}", id);
    10. cache.remove(id);
    11. });
    12. //连接异常
    13. sseEmitter.onError(throwable -> {
    14. log.info("连接异常:{}", id);
    15. cache.remove(id);
    16. });
    17. //连接超时
    18. sseEmitter.onTimeout(() -> {
    19. log.info("连接超时:{}", id);
    20. cache.remove(id);
    21. });
    22. return sseEmitter;
    23. }
    2、推送
    1. @GetMapping(path = "push/{userId}")
    2. public String push(@PathVariable String userId,@RequestBody Map param) throws IOException {
    3. try {
    4. SseEmitter sseEmitter = cache.get(userId);
    5. if (sseEmitter != null) {
    6. sseEmitter.send(SseEmitter.event().name("msg").data("后端发送消息:" + param));
    7. }
    8. } catch (IOException e) {
    9. log.error("用户[{}]推送异常:{}", userId, e.getMessage());
    10. cache.remove(userId);
    11. }
    12. return "over";
    13. }
    3、关闭
    1. @GetMapping(path = "over")
    2. public String over(@RequestParam(name = "id", required = false) String id) {
    3. SseEmitter sseEmitter = cache.get(id);
    4. if (sseEmitter != null) {
    5. sseEmitter.complete();
    6. cache.remove(id);
    7. }
    8. return "over";
    9. }

  • 相关阅读:
    四旋翼无人机学习第4节--STM32、MPU9250等器件的绘制
    计算小于或等于n的非负整数区间包含的1的数量
    刷题之Leetcode283题(超级详细)
    Vue+SpringBoot实现评论功能
    数据结构之手撕链表(讲解➕源代码)
    leetcode刷题笔记——二分查找
    http1和http2的主要区别
    【linux API分析】module_init
    【Eclipse】Plug-in Development 插件的安装
    【洛谷 P3853】[TJOI2007] 路标设置 题解(二分答案+递归)
  • 原文地址:https://blog.csdn.net/qq_38410795/article/details/132950545