原来Spring可以这样推送消息到客户端!

服务器 服务器产品
SSE是一种允许服务器主动向客户端推送数据的技术,通常用于实现如实时通知、数据流等功能。其工作原理基于HTTP协议,客户端通过HTTP请求订阅服务器的事件流,服务器则通过SseEmitter对象持续向客户端发送事件。

哈喽,大家好,我是了不起。

Spring框架中可以使用SseEmitter实现服务端向客户端推送消息,今天盘一盘。

SseEmitter简介

SseEmitter是Spring Framework中用于服务器发送事件(Server-Sent Events, SSE)的类。SSE是一种允许服务器主动向客户端推送数据的技术,通常用于实现如实时通知、数据流等功能。其工作原理基于HTTP协议,客户端通过HTTP请求订阅服务器的事件流,服务器则通过SseEmitter对象持续向客户端发送事件。

SseEmitter的核心特性

  • 单向通信:SSE是单向的,只允许服务器向客户端推送数据,客户端不能通过此通道向服务器发送数据。
  • 基于HTTP:SSE使用标准的HTTP协议,因此不需要额外的协议支持,易于实现和使用。
  • 自动重连:如果连接中断,客户端浏览器会自动尝试重新连接服务器。
  • 事件流格式:SSE使用简单的文本格式传输数据,每条消息以data:开头,并以两个换行符\n\n结束

SseEmitter的使用场景

  • 实时数据流:在需要实时数据更新的应用中,如股票交易平台,服务器可以使用SseEmitter向客户端推送最新的股票价格和交易信息。
  • 实时通知:适用于需要向用户发送实时通知的场景,例如在线教育平台的新课程发布或作业提交通知。
  • 聊天应用:在聊天应用中,SseEmitter可以用来实现实时消息推送,提高消息传递的效率。
  • 监控系统:在监控系统中,SseEmitter可以用于实时推送监控数据,如物联网项目中传感器采集的数据,以实时监控设备状态。

SseEmitter的基本用法

  • 创建SseEmitter实例:在控制器中创建一个SseEmitter实例,并将其返回给客户端。
  • 发送事件:通过SseEmitter实例的send方法向客户端发送事件。
  • 处理连接关闭:通过SseEmitter的onCompletion和onTimeout方法处理连接关闭或超时的情况。
  • 通过SseEmitter,开发者可以构建出高效、可靠的实时应用,提升用户体验和系统性能。

下面我们通过一个简单示例演示下

前端服务

使用Vue CLI创建一个Vue 3项目

安装Vue CLI
npm install -g @vue/cli
创建Vue 3项目
vue create my-vue3-app
启动服务
cd my-vue3-app
npm run serve

创建一个vue文件EventList.vue

获取消息,然后进行等待服务端的消息。

<template>
  <div>
    <h1>Server-Sent Events</h1>
    <ul>
      <li v-for="message in messages" :key="message.id">{{ message.content }}</li>
    </ul>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { SseClient } from './SseClient';


const messages = ref([]);

const sseClient = new SseClient((event) => {
  const data = JSON.parse(event.data);
  messages.value.push(data);
});

onMounted(() => {
  sseClient.connect();
});

onUnmounted(() => {
  sseClient.disconnect();
});
</script>

<style scoped>
/* Add your styles here */
</style>

创建JS文件SseClient

export class SseClient {
    constructor(onMessage) {
      this.onMessage = onMessage;
      this.eventSource = null;
    }
  
    connect() {
      this.eventSource = new EventSource('http://localhost:8089/events/54321');
      this.eventSource.onmessage = (event) => {
        this.onMessage(event);
      };
      this.eventSource.onerror = (error) => {
        this.disconnect();
      };
    }
  
    disconnect() {
      if (this.eventSource) {
        this.eventSource.close();
        this.eventSource = null;
      }
    }
  }

然后再Vue项目入口 APP.vue中引入刚才的Vue文件。

后端服务

创建SpringBoot服务

直接写一个简易的Controller,将SseEmitter 缓存起来,可以直接进行消息发送。

@Controller
public class SseEmitterController {
    private static Map<String, SseEmitter> sseCache = new ConcurrentHashMap<>();

    @CrossOrigin(origins = "*")
    @GetMapping("/events/{userId}")
    public SseEmitter stream(@PathVariable String userId) throws IOException {
        sseCache.put(userId,new SseEmitter(10 * 60 * 1000L));
        SseEmitter emitter = sseCache.get(userId);
        Map<String,String> map = new HashMap<>();
        map.put("id", userId);
        map.put("content", "连接成功");
        emitter.send(map);
        return emitter;
    }

    @GetMapping("/sendMessage/{userId}")
    public String sendMessage(@PathVariable String userId,
                              @RequestParam(name = "message", required = false) String message) throws IOException {
        SseEmitter emitter = sseCache.get(userId);
        Map<String,String> map = new HashMap<>();
        map.put("id", userId);
        map.put("content", message);
        emitter.send(map);
        return "成功";
    }

    @GetMapping("/close/{userId}")
    public String close(@PathVariable String userId
                              ) throws IOException {
        SseEmitter emitter = sseCache.get(userId);
        emitter.complete();
        return "成功";
    }
}

前后端启动后联调:

初始化连接成功。

图片图片

再手动发送消息。

图片图片

客户端接收消息:

图片图片

以上是一个简易的服务端主动推送消息给客户端的例子。

责任编辑:武晓燕 来源: Java技术指北
相关推荐

2021-09-22 15:46:29

虚拟桌面瘦客户端胖客户端

2011-08-17 10:10:59

2011-04-11 16:33:52

Oracle客户端

2010-05-31 10:11:32

瘦客户端

2011-03-02 14:36:24

Filezilla客户端

2011-03-24 13:00:31

配置nagios客户端

2010-12-21 11:03:15

获取客户端证书

2011-10-26 13:17:05

2013-09-18 10:44:01

搜狗输入法词语

2024-11-19 09:15:40

搜索类型MySQL

2012-12-18 09:34:49

2011-03-21 14:53:36

Nagios监控Linux

2011-04-06 14:24:20

Nagios监控Linux

2013-05-09 09:33:59

2009-03-04 10:27:50

客户端组件桌面虚拟化Xendesktop

2024-10-16 08:51:57

2010-02-22 09:03:22

零客户端瘦客户端VDI终端

2011-03-25 14:25:38

NagiosWindows监控

2009-11-17 15:02:27

Oracle客户端

2009-07-15 17:33:08

Swing客户端
点赞
收藏

51CTO技术栈公众号