使用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接口是两个通道,不要混淆了。
热门推荐
专家详解:颈椎拉伤后的正确躺卧姿势
6岁女童骨折后哭闹不已,医生在石膏上彩绘卡通图助她缓解紧张情绪
皮蛋瘦肉粥:家常美味的秘诀
父母如何与婴儿进行亲子互动?8款亲子游戏推荐
精选内容集|低卡美味甜品推荐,无油营养健康享受甜蜜时光
如何分析汇率差异的原因?汇率差异会带来哪些影响?
说话结巴是什么原因造成的
4090D和4090区别在哪?游戏发烧友必看的价格与性能
CUDA、CUDA Toolkit、CUDNN、NVCC关系详解
老年人华山索道上下山全攻略:安全、便捷与舒适的旅程指南
俯卧撑全解析:从入门到进阶的力量训练指南
临床药物知识详解:从基础概念到新药研发进展
暑期游泳玩水要当心 武汉普瑞眼科医院提醒夏季高发眼疾「红眼病」
合同期限起始日的法律认定与实务操作
酸菜生鱼的制作方法详解(传统美食的制作步骤和技巧)
导致皮肤粗糙的原因以及如何缓解
辟谣!水蛭吸血治颈椎病并非良方,科学诊治是关键!
什么样的痣需要外科干预?
Scopus会议和期刊的区别
如何开具股票的资产证明?这种证明的开具过程有哪些注意事项?
价格欺诈向哪个部门投诉
如何才能培养高自我价值的孩子?
为什么要发展供应链金融?该怎样发展供应链金融?
全球公认最快减肥运动,每天20分钟,一周暴瘦一圈!
健身房力量训练能减肥吗
智界R7车主反馈后备箱锁品控差,厂家竟然可以上门换锁?
炖鸡汤放什么材料
开发智能化的金融市场情绪指数模型
肩部疼痛患者,应考虑到的26种诊断!
左肩颈痛怎么缓解?四种实用方法让你告别疼痛