前言:本大大找了两天,看了无数篇帖子,大多都是东扯扯,西扯扯,完全看不懂;最后万户从中一点绿,总算找到能运作的写法。因为找不到原文,在这里先感谢那位大佬!!!
一、配置
package com.linkstec.tad.rakuraku.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
二、后端具体代码实现
package com.linkstec.tad.rakuraku.common.message.controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.linkstec.tad.rakuraku.common.bean.BaseInfo;
import com.linkstec.tad.rakuraku.common.message.service.WebSocketService;
@Component
@ServerEndpoint("/webSocket/{userName}") // encoders = { ServerEncoder.class },可选值,指定编码转换器,传输对象时用到,这里直接转json就ok
public class WebSocketController {
private static final Map<String, Session> TOKEN_SESSION = new HashMap<>();
private static final Map<String, String> SESSION_ID_TOKEN = new HashMap<>();
private static final Map<String, String> SESSION_MESSAGE = new HashMap<>();
// private static final SimpleDateFormat FORMAT = new SimpleDateFormat("yyyy:MM:dd hh:mm:ss");
@Autowired
private WebSocketService webSocketService;
private static WebSocketController webSocketController;
@PostConstruct
public void refreshDate() {
webSocketController = this;
webSocketController.webSocketService = this.webSocketService;
}
@OnOpen
public void onOpen(Session session, @PathParam(value = "userName") String userName) {
System.out.println("新的连接进来了- " + session.getId());
if (userName == null) {
try {
session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "username参数为空"));
} catch (IOException e) {
throw new IllegalStateException(e.getMessage());
}
} else {
String uuid = UUID.randomUUID().toString();
String token = userName + uuid;
SESSION_ID_TOKEN.put(session.getId(), token);
TOKEN_SESSION.put(token, session);
System.out.println(token);
}
}
@OnClose
public void onColse(Session session) {
System.out.println("断开连接:" + session.getId() + "-" + SESSION_ID_TOKEN.get(session.getId()));
}
@OnMessage
public void onMessage(Session session, String message) {
System.out.println("收到客户端发来的消息:" + message + session.getId());
SESSION_MESSAGE.put(session.getId(), message);
Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(() -> {
sendMessage(session, message);
}, 1000, 1000, TimeUnit.MILLISECONDS);
}
@OnError
public void error(Session session, Throwable t) {
t.printStackTrace();
}
public void sendMessage(Session session, String message) {
System.out.println("发送全体消息");
BaseInfo baseInfo = (BaseInfo) JSONObject.toJavaObject(JSON.parseObject(message), BaseInfo.class);
Integer percentage = webSocketController.webSocketService.initialService(baseInfo);
sendMessageToTarget(SESSION_ID_TOKEN.get(session.getId()), percentage + "");
// TOKEN_SESSION.values().forEach((session) -> {
// session.getAsyncRemote().sendText(message);
// });
}
public <T> void sendMessageToTarget(String token, Object t) {
System.out.println("发送指定token消息");
try {
TOKEN_SESSION.get(token).getBasicRemote().sendText((String) t);
if (Integer.valueOf(100).equals(t)) {
Session session = TOKEN_SESSION.get(token);
session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "工程下载完成!"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
三、前端vue + element ui
downLoadProject(row, index) {
localStorage.setItem("COMMON.RUNTIME.PRJTID", row.projectId);
localStorage.setItem("COMMON.RUNTIME.PRJTCASEID", row.projectCaseId);
localStorage.setItem("COMMON.RUNTIME.STAGEID", row.stageId);
console.log("row", row);
var str = row.projectId;
if (typeof WebSocket === "undefined") {
alert("您的浏览器不支持socket");
} else {
// 实例化socket
this.socket = new WebSocket(this.path);
// 监听socket连接
this.socket.onopen = this.open;
// 监听socket错误信息
this.socket.onerror = this.error;
// 监听socket消息
this.socket.onmessage = this.getMessage;
this.socket.onclose = this.close;
}
},
open: function () {
let params = {
projectId: localStorage.getItem("COMMON.RUNTIME.PRJTID"),
projectCaseId: localStorage.getItem("COMMON.RUNTIME.PRJTCASEID"),
stageId: localStorage.getItem("COMMON.RUNTIME.STAGEID"),
};
this.socket.send(JSON.stringify(params));
console.log("socket连接成功");
},
error: function (err) {
console.log("连接错误" + err);
},
getMessage: function (msg) {
console.log(msg);
this.msg = msg.data;
},
close: function (event) {
console.log("socket已经关闭" + event.reason);
},
sendMessage() {
this.socket.send(this.sendMsg);
},
四、具体实现图
打印出来的msg对象中的data属性就是想要拿取的下载文件的进度!!!!
哦耶耶耶耶耶耶耶耶耶耶!