使用WebSocket实现前端实时刷新进度条
创作时间:
作者:
@小白创作中心
使用WebSocket实现前端实时刷新进度条
引用
CSDN
1.
https://blog.csdn.net/AsFarmer/article/details/141432676
本文将介绍如何使用WebSocket实现前端实时刷新进度条的功能。通过WebSocket的双向通信特性,可以实现在不刷新页面的情况下,实时更新前端显示的进度信息。
业务场景
领导要求开发一个根据进度实时刷新的进度条功能。为了实现这一需求,我们可以采用WebSocket这种支持双向通信的持久链接技术。
配置
首先需要在Spring Boot项目中配置WebSocket支持。创建一个配置类,启用WebSocket功能:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
@EnableWebSocket
public class WebSocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
ServerEndpointExporter exporter = new ServerEndpointExporter();
return exporter;
}
}
定义处理类
接下来定义WebSocket处理类,使用ConcurrentHashMap
存储所有活跃的WebSocket连接会话。当客户端连接时,会将当前会话保存到静态变量sessions
中;当客户端断开连接时,从sessions
中移除对应的会话。
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.time.Instant;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
@ServerEndpoint("/progress")
public class ProgressWebSocketHandler {
private static ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
private Session session;
// 收到消息
@OnMessage
public void onMessage(String message) throws IOException {
log.info("[websocket] 收到消息:id={}, message={}", this.session.getId(), message);
if (message.equalsIgnoreCase("bye")) {
// 由服务器主动关闭连接。状态码为 NORMAL_CLOSURE(正常关闭)。
this.session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "Bye"));
return;
}
this.session.getAsyncRemote().sendText("[" + this.session.getId() + "] Hello " + message);
}
// 连接打开
@OnOpen
public void onOpen(Session session, EndpointConfig endpointConfig) {
// 保存 session 到对象
this.session = session;
sessions.put(session.getId(), session);
log.info("[websocket] 新的连接:id={}", this.session.getId());
}
// 连接关闭
@OnClose
public void onClose(CloseReason closeReason) {
log.info("[websocket] 连接断开:id={}, reason={}", this.session.getId(), closeReason);
}
// 连接异常
@OnError
public void onError(Throwable throwable) throws IOException {
log.info("[websocket] 连接异常:id={}, throwable={}", this.session.getId(), throwable.getMessage());
// 关闭连接。状态码为 UNEXPECTED_CONDITION(意料之外的异常)
this.session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, throwable.getMessage()));
}
public static void sendMessage(String sessionId, String message) {
Session session = sessions.get(sessionId);
if (session != null && session.isOpen()) {
try {
session.getAsyncRemote().sendText("[" + session.getId() + "] Hello " + message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
测试链接
使用Postman或APIFox创建一个WebSocket链接,地址格式为ws://
+主机+端口+你指定的ServerEndpoint
路径名。例如,在本地测试时,WebSocket所在的微服务端口号为8118,处理类使用了@ServerEndpoint("/progress")
,那么链接地址为ws://localhost:8118/progress
。
点击链接,出现提示说明连接成功。可以发送一些消息进行测试,中括号里的数组就是sessionId(连接Id)。
业务代码
前端代码
前端代码负责建立WebSocket连接,并将sessionId传递给后端。
getProgress() {
this.isFinish = false;
return new Promise((resolve, reject) => {
const id = this.generateUniqueId();
// 假设WebSocket服务的URL是 ws://yourserver.com/templates/variables
const socket = new WebSocket("ws://localhost:8118/progress?");
// 连接打开时触发的函数
socket.onopen = (event) => {
socket.send(this.id);
};
// 接收到服务器消息时触发的函数
socket.onmessage = (event) => {
let process = event.data.split(": ");
if (process.length > 1) {
this.process = process[1].replace("%", "");
}
if (this.process == "100") {
this.isFinish = true;
}
let match = event.data.match(/\[(\d+)\]/);
if (match) {
let result_number = match[1];
this.id = result_number;
resolve(this.id);
}
};
// 连接关闭时触发的函数
socket.onclose = function (event) {
if (event.wasClean) {
console.log("WebSocket 连接已正常关闭");
} else {
// 例如,服务器进程被杀死或网络中断
console.log("WebSocket 连接意外关闭");
}
console.log("关闭代码: " + event.code + " 关闭原因: " + event.reason);
};
// 发生错误时触发的函数
socket.onerror = function (error) {
console.error("WebSocket 发生错误:", error);
};
});
}
后端代码
在业务接口形参里接收前端传过来的sessionId,在你写的业务逻辑代码里面调用sendMessage方法,返回数据给前端。在测试软件上测试你的业务接口,这是你的业务代码接口,跟websocket接口是两个通道,不要混淆了。
热门推荐
Android Systrace 基础知识 - Vsync 解读
三人座沙发尺寸标准及选购要点
三人座沙发一般多长的?如何挑选适合你的沙发
每周市场洞察|“两会”提振国内市场信心,美股或面临政策挑战
手术麻醉不要慌,这些知识你要知道!
手抖一般做什么检查
不吃药,约42%高血压患者能在6年内恢复正常血压,但是实现自愈有前提
手抖人群饮食必知:三大原则与禁忌
冬天煮熟的红薯隔夜后还能吃吗?
奶粉水温50度对婴儿来说热吗
官宣:广东粤西第二条时速350公里高铁即将动工!正线长139公里
锄禾为什么改成悯农(《悯农》背后的故事)
《凡人修仙传》紫灵仙子(淡雅篇)
曾经火遍全国的茶油,人称“长寿油”,为何现在很少有人吃了?
正官日柱详解:八字命理中的正直与成就
《泰拉瑞亚》1.4召唤师挑战月总Boss装备配置攻略
紫外线灭蚊灯,安全距离你了解多少
测眼压有什么作用
职称和社保有什么关系?
快递被商家私自拦截,如何赔偿
故事结尾的4种类型
掌握数据可视化关键步骤,提升信息呈现效率
南孔圣地、江南古塞……解码衢州文化基因
晚上吃水果对身体有益还是有害?
春节的鱼都怎么吃
固态硬盘是什么意思?全面解析其原理、优势与应用
吉利和沃尔沃合作带来了哪些技术突破
洛神赋取名男孩,洛神赋典故中的男孩名字
建筑垃圾分选设备的工艺流程:资源回收的绿色篇章
创新种养结合新模式,开启高质量肉牛发展密码