WebSocket下载进度条示例
1、服务端
1)、引入websocket依赖
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2)、开启WebSocket支持
WebSocketConfig.java
@Configuration
public class WebSocketConfig {
/**
* 注入一个ServerEndpointExporter,该Bean会自动注册
* 使用@ServerEndpoint注解申明的websocket endpoint
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3)、新建WebSocket的进度条通信类
PercentWebSocket.java
@Slf4j
@Component
@ServerEndpoint(value = "/percent/{sid}")
public class PercentWebSocket {
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
*/
private static final ConcurrentHashMap<String, Session> SESSION_POOLS = new ConcurrentHashMap<>();
/**
* 连接建立成功调用的方法
*
* @param session 会话
* @param sid 模块ID
*/
@OnOpen
public void onOpen(Session session, @PathParam(value = "sid") String sid) {
SESSION_POOLS.put(sid, session);
log.info("模块【{}】开始加载", sid);
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(@PathParam(value = "sid") String sid) {
SESSION_POOLS.remove(sid);
log.info("模块【{}】加载完成", sid);
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) throws InterruptedException {
log.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
int percentage = 0;
while (percentage <= 100) {
percentage += RandomUtils.nextInt(1, 10);
this.sendMessage(percentage, session);
Thread.sleep(500);
}
percentage = 100;
this.sendMessage(percentage, session);
}
@OnError
public void onError(Throwable error) {
error.printStackTrace();
log.info("发生错误:{}", error.getMessage());
}
private void sendMessage(int percentage, Session session) {
try {
log.info("服务端给客户端[{}]发送消息{}", session.getId(), percentage);
session.getBasicRemote().sendText(String.valueOf(percentage));
} catch (Exception e) {
log.error("服务端发送消息给客户端失败:{0}", e);
}
}
}
2、客户端
<!DOCTYPE HTML>
<html>
<head>
<title>进度条</title>
</head>
<body style="text-align: center">
<progress style="width: 300px;height: 50px" id="percent" value='0' max='100'></progress>
<br>
sid:<input id="sid" name="sid" type="text" value="10"/><br>
<button onclick="openSocket()">open</button>
<button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message"></div>
</body>
<script type="text/javascript">
let websocket = null;
function openSocket() {
const pro = document.getElementById("percent");
const sid = document.getElementById('sid').value;
const socketUrl = "ws://127.0.0.1:9999/lapeace/percent/" + sid;
//判断当前浏览器是否支持WebSocket, 主要此处要更换为自己的地址
if ('WebSocket' in window) {
websocket = new WebSocket(socketUrl);
} else {
alert('Not support websocket')
}
//连接发生错误的回调方法
websocket.onerror = function () {
setMessageInnerHTML("error");
};
//连接成功建立的回调方法
websocket.onopen = function (event) {
setMessageInnerHTML("open");
}
//接收到消息的回调方法
websocket.onmessage = function (event) {
if (event.data < 100) {
pro.value = event.data;
} else {
pro.value = event.data;
setMessageInnerHTML("加载完成!");
websocket.close();
}
}
//连接关闭的回调方法
websocket.onclose = function () {
setMessageInnerHTML("close");
}
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
websocket.close();
}
}
//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
//关闭连接
function closeWebSocket() {
websocket.close();
}
//发送消息
function send() {
const message = document.getElementById('sid').value;
websocket.send(message);
}
</script>
</html>