网站建设 回本,厦门网站建设建站中心,wordpress自定义模板下载,企业咨询培训前言
大家好#xff0c;我是雪荷。最近我在灵犀 BI 项目中引入了 SSE 技术#xff0c;以保证图表的实时渲染#xff0c;当图表渲染完毕服务端推送消息至浏览器端触发重新渲染。 什么是 SSE#xff1f;
SSE 全称为 Server-Send Events 意思是服务端推送事件。 SSE 相比于 …前言
大家好我是雪荷。最近我在灵犀 BI 项目中引入了 SSE 技术以保证图表的实时渲染当图表渲染完毕服务端推送消息至浏览器端触发重新渲染。 什么是 SSE
SSE 全称为 Server-Send Events 意思是服务端推送事件。 SSE 相比于 Websocket 它基于 Http 实现无需实现其他协议、更加轻量级、支持自动重连但只能服务端推送消息给客户端客户端不能推送消息给服务端。适用于服务端主动推送数据客户端只需接收数据的场景。以下为 SSE 与 Websocket 的对比
SSEWebsocket通信单向通信服务端到客户端双向通信协议HttpWebsocket自动重连支持不支持要客户端自行支持数据格式文本格式如果要二进制数据得自行编码默认二进制数据、支持文本格式浏览器兼容性大部分支持主流浏览器支持较好 Vue Spring Boot 实现一个 SSE demo
后端实现
由于 SSE 基于 http 协议实现因此我们无需引入第三方 jar 包。首先通过 idea 创建一个 spring boot 项目记得勾选 spring web 依赖。 创建一个跨域配置因为前后端的端口不同会出现请求跨域。
Configuration
public class CorsConfig implements WebMvcConfigurer {
Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping(/**).allowedOriginPatterns(*).allowedMethods(GET, POST, PUT, DELETE).allowedHeaders(*).allowCredentials(true);}
}
随后创建一个 SSEcontroller用来创建 SSE 连接和推送消息给客户端。RestController
RequestMapping(/sse)
public class SSEController {
private static final MapInteger, SseEmitter sseEmitters new ConcurrentHashMap();
GetMapping(/create)public SseEmitter createSSEConnection() {// 创建SSE连接SseEmitter emitter new SseEmitter();// 将 sseEmitter 赛道 map 中方便管理多个 sse 连接比如可以为每个用户创建一个 sse 连接以用户 id 为 map 的 keysseEmitters.put(1, emitter);emitter.onCompletion(() - sseEmitters.remove(1));emitter.onTimeout(() - sseEmitters.remove(1));return emitter;}
PostMapping(/send)public void sendSSEMessage() {// 发送消息SseEmitter sseEmitter sseEmitters.get(1);if (sseEmitter ! null) {for (int i 0; i 3; i) {try {sseEmitter.send(SseEmitter.event().data(hello world) // 发送的数据是 Object 类型.name(sse-message)); // 定义 SSE 事件的名称方便前端监听} catch (IOException e) {sseEmitters.remove(1);}}}}
}
在上面的代码中createSSEConnection 用来创建 sse 连接注意其请求方法为 getpost 是不能创建的因为前端发的就是 get 请求。我还创建了一个 sseEmitters 的 MapInteger, SseEmitter 来管理 sse 连接在项目中 map 的 key 可以作为客户端标识可以是用户 id 或者某些业务参数。当创建完毕后将 sseEmiter 塞到 map 中当 sse 连接超时或者完成就删掉在 map 中对应的 value。
而 sendSSEMessage 方法就是服务端向客户端推送消息的实例代码这里我们方便我写了一个请求来触发服务端发消息给客户端实际是根据具体业务来主动推消息给客户端。比如异步生成图表或者插入数据时当此动作完毕后可以发消息给前端表明操作成功。那如何发送消息就不用我说了先从 map 取出 sseEmitter接着添加事件名和要发送的数据就好了。 如果是前端传送参数来创建 sse 连接的话可以这样操作。 GetMapping(/create)public SseEmitter createSSEConnection(RequestParam Integer id) {// 创建SSE连接SseEmitter emitter new SseEmitter();sseEmitters.put(id, emitter);emitter.onCompletion(() - sseEmitters.remove(1));emitter.onTimeout(() - sseEmitters.remove(1));return emitter;}
前端实现
首先创建一个 vue 项目引入一些基础依赖比如 aixos项目具体结构如下 myAxios.js
import axios from axios;
const myAxios axios.create({baseURL: http://localhost:8080,
})
myAxios.defaults.withCredentials true; //设置为true
export default myAxios;
然后 SSEDemo.vue 就是主要创建 sse 连接和接受服务端发送消息
SSEDemo.vue
templatedivh3接收到的消息:/h3ulli v-for(message, index) in messages :keyindex{{ message }}/li/ul/divbutton clicksendMessage发送消息/button
/template
script
import {onBeforeUnmount, onMounted, ref} from vue;
import myAxios from /plugins/myAxios.js;
export default {setup() {const messages ref([]); // 存储接收到的消息let eventSource null; // 用于保存 EventSource 实例
onMounted(() {// 创建 EventSource 实例连接到服务器端的 SSE 端点eventSource new EventSource(http://localhost:8080/sse/create);
// 监听特定事件名 sse-messageeventSource.addEventListener(sse-message, (event) {console.log(收到消息:, event.data);// 解析消息并保存到 messages 中messages.value.push(event.data);});
// 监听连接关闭或错误eventSource.onerror (error) {console.error(SSE 连接出错:, error);eventSource.close(); // 关闭连接};});
onBeforeUnmount(() {// 组件销毁时关闭 SSE 连接if (eventSource) {eventSource.close();}});
const sendMessage async () {await myAxios.post(/sse/send);}
return {messages,sendMessage};},
};
/script
new EventSource 新建一个事件源其会向后端发送请求方法为 get 的 http 请求利用 eventSource.addEventListener 创建一个事件监听器并带上事件名就可以完成事件的监听和消息发送啦。
最后运行前后端项目打开前端地址会看到有一个 http 显示待处理。 点击发送消息按钮使后端发送消息给前端前端接收到就会实时显示。 开源项目
厚米匹配
网址厚米匹配系统
前端仓库https://github.com/dnwwdwd/homieMatching-fronted
后端仓库https://github.com/dnwwdwd/homieMatching 灵犀 BI
网址鱼智能 BI
前端仓库https://github.com/dnwwdwd/Lingxi-BI-fronted
后端仓库https://github.com/dnwwdwd/Lingxi-BI