使用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接口是两个通道,不要混淆了。
热门推荐
本田思域适合使用哪种机油?
ChemDraw对齐功能使用指南:从菜单调用到网格线设置
人均食醋15斤/年,山西为啥还将“醋都”输给了镇江?
如何运用黄金分割法来构图
女性长期佩戴“银手镯”,真的对身体好吗?医生说出了答案
如何用针和钩编的方式编织裙子:编织裙子的详细方案和方法
毛线编织的基本方法与技巧
红葡萄酒保质期多长时间,揭秘红酒的“生命曲线”
期货牛人观点:市场趋势与交易策略
多音字的学习方法总结
非自愿离职被要求写自愿离职怎么办
国际金融分析师CFA证书的含金量及职业发展前景
八字中年离乱是什么意思,中年离乱于不意中失败
有助于骨折恢复的水果推荐,营养助力康复!
人工智能企业如何盈利
数字内容体验的A/B测试如何优化用户体验?
翡翠文化:黄翡与黄龙玉的鉴别与价值评估
重庆做肠镜检查医院哪家好
医生、影像科注意!这一项收费医保经常违规
身份证复印件如何安全地写上特殊用途说明?
生肖猪:佩戴金银玉器的风水影响与选择指南
如何选择一个好的商铺?这些选址要点和购买技巧请收好
熟普洱茶等级划分与价格定位:从入门到收藏的全面指南
铁矿石价格与哪些因素相关?这些因素如何影响市场供需?
如何有效实施知识管理以提升团队效率?
2024年成人高考改革:应对策略与变化解析
离职通知书模板:简洁明了的离职信范文
夏季也是咽喉炎高发期,中医教你有效舒缓喉咙不适
宇宙中的高等文明:卡尔达舍夫等级解析
企业财税合规:保障经营合法性与稳定性的必由之路