修正,DBName加密后不一致问题,添加远程控制(双端)的请求控制,断开控制功能(待测试)

This commit is contained in:
republicline 2024-07-22 18:42:04 +08:00
parent f5ef4fd0b7
commit 7a1e31517b
8 changed files with 287 additions and 96 deletions

2
.gitignore vendored
View File

@ -2,7 +2,7 @@
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
/logs
### STS ###
.settings/
.apt_generated

View File

@ -22,9 +22,9 @@ public class WebSocketConfig implements WebSocketConfigurer {
registry.addHandler(medicineHandler(), "/rax/vitalSignsMedicine")
.addHandler(chatHandler(), "/rax/chatRoom")
.addHandler(addMedicineHandler(), "/rax/addMedicine")
.addHandler(machineHandler(),"/rax/getMedicine")
.addHandler(machineFeedbackHandler(),"/rax/getMedicine")
// .addInterceptors(new HttpSessionHandshakeInterceptor())
.addInterceptors(webSocketHandshakeInterceptor())
// .addInterceptors(webSocketInterceptors())
.setAllowedOrigins("*");
}
@ -44,12 +44,12 @@ public class WebSocketConfig implements WebSocketConfigurer {
}
@Bean
public WebSocketHandler machineHandler() {
public WebSocketHandler machineFeedbackHandler() {
return new MachineFeedbackHandler();
}
@Bean
public HandshakeInterceptor webSocketHandshakeInterceptor() {
public HandshakeInterceptor webSocketInterceptors() {
return new WebSocketInterceptors();
}
}

View File

@ -4,15 +4,11 @@ import com.alibaba.fastjson.JSONObject;
import com.rax.vital.timer.AIMedicineTimer;
import com.rax.vital.timer.VitalSignTimerWS;
import com.rax.vital.util.DatabaseNameUtil;
import com.rax.vital.util.GetHttpParamUtil;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.web.socket.*;
import java.net.URLDecoder;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
@ -29,12 +25,13 @@ public class AddMedicineHandler implements WebSocketHandler {
@Resource
private OAuth2AuthorizationService authorizationService;
// @Autowired
// private AIMedicineTimer aiMedicineTimer;
// 发送心跳任务的定时任务容器
private Map<String, ScheduledExecutorService> timerTaskMap = new ConcurrentHashMap();
@Autowired
private AIMedicineTimer aiMedicineTimer;
@Override
public void afterConnectionEstablished(WebSocketSession session) {
vitalSignTimerWS.setWSAIFlagSession(session);
@ -43,26 +40,76 @@ public class AddMedicineHandler implements WebSocketHandler {
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
String decode = URLDecoder.decode(session.getUri().getQuery());
Map params = GetHttpParamUtil.getParams(decode);
String token = (String) params.get("token");
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
String username = authorization.getPrincipalName();
// String decode = URLDecoder.decode(session.getUri().getQuery());
// Map params = GetHttpParamUtil.getParams(decode);
// String token = (String) params.get("token");
// OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
// String username = authorization.getPrincipalName();
JSONObject jsonObject = JSONObject.parseObject((String) message.getPayload());
if (!"heartbeat".equals(jsonObject.getString("msgType"))) {
String msgType = jsonObject.getString("msgType");
if (!"heartbeat".equals(msgType)) {
// 病人名
String patientName = jsonObject.getString("patientName");
// 病人身份证
String idNum = jsonObject.getString("idNum");
// yyyyMMdd
String date = jsonObject.getString("date");
System.out.println("addMedicineHandler-json = " + jsonObject.toJSONString());
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
vitalSignTimerWS.changeWSAIFlag(databaseName, username, session, jsonObject.getString("flag"),
System.out.println("addMedicineHandler-databaseName = " + databaseName);
// 将网站端的dbName作为key session作为Value存入Map 以便后续判断状态
aiMedicineTimer.initWeb(databaseName, session, false);
if (aiMedicineTimer.getUnitySession(databaseName) != null) {
JSONObject result = new JSONObject();
result.put("msg", "unity端已登录");
result.put("msgType", "msg");
session.sendMessage(new TextMessage(result.toJSONString().getBytes()));
} else {
JSONObject result = new JSONObject();
result.put("msg", "unity端未登录");
result.put("msgType", "msg");
session.sendMessage(new TextMessage(result.toJSONString().getBytes()));
}
if (aiMedicineTimer.getWebSession(databaseName) != null) {
JSONObject result = new JSONObject();
result.put("msg", "网页端已登录");
result.put("msgType", "msg");
session.sendMessage(new TextMessage(result.toJSONString().getBytes()));
WebSocketSession unitySession = aiMedicineTimer.getUnitySession(databaseName);
if (unitySession != null) {
unitySession.sendMessage(new TextMessage(result.toJSONString().getBytes()));
}
}
// 处理网页端接收到消息后的相应内容
if ("webResponseConnection".equals(msgType)) {
String webConnectionFlag = jsonObject.getString("webConnectionFlag");
// 给unity端发送网页端拒绝连接
aiMedicineTimer.sendConnectionResponseToUnity(databaseName, webConnectionFlag);
}
// 处理web端请求或断开连接
if ("webRequestConnection".equals(msgType)) {
String webRequestFlag = jsonObject.getString("webRequestFlag");
aiMedicineTimer.sendWebRequestConnectionMsg(databaseName, webRequestFlag);
}
// 处理发送给药相关
if (aiMedicineTimer.getWebSession(databaseName) != null && aiMedicineTimer.getUnitySession(databaseName) != null
&& aiMedicineTimer.isReady(databaseName)) {
// todo 注意修改
vitalSignTimerWS.changeWSAIFlag(databaseName, "admin", session, jsonObject.getString("flag"),
jsonObject.getString("medicine"), jsonObject.getString("value"));
}
}
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) {
@ -72,7 +119,7 @@ public class AddMedicineHandler implements WebSocketHandler {
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
stopHeartbeat(session);
vitalSignTimerWS.removeWSAIFlagSession(session);
System.out.println(this.getClass().getName() + " Connection closed:" + closeStatus.getReason());
aiMedicineTimer.closeConnection(session);
}
@Override
@ -107,4 +154,6 @@ public class AddMedicineHandler implements WebSocketHandler {
ScheduledExecutorService heartbeatExecutor = timerTaskMap.get(session.getId());
heartbeatExecutor.shutdownNow();
}
}

View File

@ -50,6 +50,7 @@ public class ChatHandler implements WebSocketHandler {
String msg = jsonObject.getString("msg");
System.out.println("chatHandler-jsonObject = " + jsonObject.toJSONString());
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
System.out.println("chatHandler-databaseName = " + databaseName);
chatService.sendMessage(databaseName,username,session, msg);
}
}

View File

@ -5,9 +5,7 @@ import com.rax.vital.timer.AIMedicineTimer;
import com.rax.vital.timer.VitalSignTimerWS;
import com.rax.vital.util.DatabaseNameUtil;
import jakarta.annotation.Resource;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.web.socket.*;
import java.util.Map;
@ -20,18 +18,15 @@ import java.util.concurrent.TimeUnit;
* 仪器获取网站给药信息
*/
public class MachineFeedbackHandler implements WebSocketHandler {
@Resource
private OAuth2AuthorizationService authorizationService;
@Resource
private VitalSignTimerWS vitalSignTimerWS;
// @Autowired
// private AIMedicineTimer aiMedicineTimer;
private Map<String, ScheduledExecutorService> timerTaskMap = new ConcurrentHashMap();
@Autowired
private AIMedicineTimer aiMedicineTimer;
@Override
public void afterConnectionEstablished(WebSocketSession session) {
@ -44,7 +39,8 @@ public class MachineFeedbackHandler implements WebSocketHandler {
JSONObject jsonObject = JSONObject.parseObject((String) message.getPayload());
if (!"heartbeat".equals(jsonObject.getString("msgType"))) {
String msgType = jsonObject.getString("msgType");
if (!"heartbeat".equals(msgType)) {
// 病人名
String patientName = jsonObject.getString("patientName");
// 病人身份证住院号
@ -53,18 +49,56 @@ public class MachineFeedbackHandler implements WebSocketHandler {
String date = jsonObject.getString("date");
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
String code = jsonObject.getString("code");
// aiMedicineTimer.addU3DSession(databaseName,session);
// aiMedicineTimer.addU3DStatusMap(databaseName, false); // 初始状态为false
aiMedicineTimer.initUnity(databaseName, session, session);
// u3d发送表示请求与网页端的连接
if ("unityRequestConnection".equals(msgType)) {
String unityConnectionFlag = jsonObject.getString("unityConnectionFlag");
// u3d端请求网页端连接或断开
aiMedicineTimer.sendUnityRequestConnectionMsg(databaseName, unityConnectionFlag);
}
// u3d相应网页端的请求
if ("unityResponseConnection".equals(msgType)) {
String unityConnectionFlag = jsonObject.getString("unityConnectionFlag");
aiMedicineTimer.sendConnectionResponseToWeb(databaseName, unityConnectionFlag);
}
if (aiMedicineTimer.getWebSession(databaseName) != null) {
JSONObject result = new JSONObject();
result.put("msg", "网站端已登录");
result.put("msgType", "msg");
session.sendMessage(new TextMessage(result.toJSONString().getBytes()));
} else {
JSONObject result = new JSONObject();
result.put("msg", "网站端未登录");
result.put("msgType", "msg");
session.sendMessage(new TextMessage(result.toJSONString().getBytes()));
}
if (aiMedicineTimer.getUnitySession(databaseName) != null) {
JSONObject result = new JSONObject();
result.put("msg", "unity端已登录");
result.put("msgType", "msg");
session.sendMessage(new TextMessage(result.toJSONString().getBytes()));
WebSocketSession webSession = aiMedicineTimer.getWebSession(databaseName);
if (webSession != null) {
webSession.sendMessage(new TextMessage(result.toJSONString().getBytes()));
}
}
if (aiMedicineTimer.getUnitySession(databaseName) != null && aiMedicineTimer.getWebSession(databaseName) != null
&& aiMedicineTimer.isReady(databaseName)) {
vitalSignTimerWS.sendMachineFlag(databaseName, code, session);
String connection = jsonObject.getString("connection");
if ("true".equals(connection)) {
// 设备端口请求连接
// 广播到网站段端
}
}
}
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) {
@ -74,7 +108,7 @@ public class MachineFeedbackHandler implements WebSocketHandler {
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
stopHeartbeat(session);
vitalSignTimerWS.removeMachineSessionMap(session);
System.out.println(this.getClass().getName() + " Connection closed:" + closeStatus.getReason());
aiMedicineTimer.closeConnection(session);
}
@Override

View File

@ -3,17 +3,15 @@ package com.rax.vital.handler;
import com.alibaba.fastjson.JSONObject;
import com.rax.vital.timer.VitalSignTimerWS;
import com.rax.vital.util.DatabaseNameUtil;
import com.rax.vital.util.GetHttpParamUtil;
import jakarta.annotation.Resource;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.web.socket.*;
import java.net.URLDecoder;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 生命体征和标志位信息
@ -35,11 +33,11 @@ public class MedicineHandler implements WebSocketHandler {
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
String decode = URLDecoder.decode(session.getUri().getQuery());
Map params = GetHttpParamUtil.getParams(decode);
String token = (String) params.get("token");
OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
String username = authorization.getPrincipalName();
// String decode = URLDecoder.decode(session.getUri().getQuery());
// Map params = GetHttpParamUtil.getParams(decode);
// String token = (String) params.get("token");
// OAuth2Authorization authorization = authorizationService.findByToken(token, OAuth2TokenType.ACCESS_TOKEN);
// String username = authorization.getPrincipalName();
String payload = (String) message.getPayload();
JSONObject jsonObject = JSONObject.parseObject(payload);
@ -49,10 +47,9 @@ public class MedicineHandler implements WebSocketHandler {
String idNum = jsonObject.getString("idNum");
String date = jsonObject.getString("date");
System.out.println("medicineHandler-jsonObject = " + jsonObject.toJSONString());
String databaseName = null;
databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
String databaseName = DatabaseNameUtil.encrypt(patientName) + "_" + DatabaseNameUtil.encrypt(idNum) + "_" + date;
System.out.println("medicineHandler-databaseName = " + databaseName);
vitalSignTimerWS.createAndSendWSMessageMongo(databaseName, username, session);
vitalSignTimerWS.createAndSendWSMessageMongo(databaseName, "admin", session);
}
}

View File

@ -18,6 +18,7 @@ public class WebSocketInterceptors implements HandshakeInterceptor {
@Resource
private OAuth2AuthorizationService authorizationService;
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
String decode = URLDecoder.decode(request.getURI().getQuery());

View File

@ -1,71 +1,180 @@
package com.rax.vital.timer;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import java.io.IOException;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
@RefreshScope
@Component
@RequiredArgsConstructor
public class AIMedicineTimer {
// MongoDB的地址
@Value("${vital-sign.mongodb.host}")
private String mongoDBHost;
// MongoDB的用户名
@Value("${vital-sign.mongodb.username}")
private String mongoUsername;
// 存放sessionId与dbName的映射关系
private static final Map<String, WebSocketSession> webDbSessionMap = new ConcurrentHashMap();
// MongoDB的用户的密码
@Value("${vital-sign.mongodb.password}")
private String mongoPassword;
// 存放sessionId的状态
private static final Map<WebSocketSession, Boolean> webSessionStatusMap = new ConcurrentHashMap();
// mysql地址
@Value("${vital-sign.mysql.host}")
private String mysqlHost;
// unity 端的dbname sessionId 映射
private static final Map<String, WebSocketSession> u3DDbSessionMap = new ConcurrentHashMap<>();
// mysql用户名
@Value("${vital-sign.mysql.username}")
private String mysqlUsername;
// unity端的session状态映射
private static final Map<WebSocketSession, Boolean> u3DStatusMap = new ConcurrentHashMap<>();
// mysql用户密码
@Value("${vital-sign.mysql.password}")
private String mysqlPassword;
// 定时任务容器
private static final Map<String, TimerTask> timerTaskMap = new ConcurrentHashMap<>();
// web端状态容器 key:sessionId value:boolean
private static final Map<String, Boolean> webStatusMap = new ConcurrentHashMap<>();
// u3D端状态容器 key:sessionId value:boolean
private static final Map<String, Boolean> u3DStatusMap = new ConcurrentHashMap<>();
// key: dbName value: sessionId
private static final Map<String, String> webSession = new ConcurrentHashMap<>();
// key: dbName value: sessionId
private static final Map<String, String> u3DSession = new ConcurrentHashMap<>();
public void addWebSession(String dbName, WebSocketSession session) {
webSession.put(dbName, session.getId());
// unity响应web端的信息
public void sendConnectionResponseToWeb(String databaseName, String flag) throws IOException {
WebSocketSession webSession = getWebSession(databaseName);
if (webSession != null) {
JSONObject unityMsg = new JSONObject();
if ("1".equals(flag)) {
// unity同意连接
setU3DStatus(databaseName, true);
unityMsg.put("msgType", "unityResponseConnection");
unityMsg.put("unityConnectionFlag", "1");
webSession.sendMessage(new TextMessage(unityMsg.toJSONString().getBytes()));
}
if ("0".equals(flag)) {
// 网页端拒绝连接
setU3DStatus(databaseName, false);
unityMsg = new JSONObject();
unityMsg.put("msgType", "unityResponseConnection");
unityMsg.put("unityConnectionFlag", "0");
webSession.sendMessage(new TextMessage(unityMsg.toJSONString().getBytes()));
// 把网页端的sessionStatus置为false
setWebStatus(databaseName, false);
}
} else {
// 告知u3d网页端
System.out.println("U3d尚未初始化无法发送连接响应消息");
WebSocketSession webSocketSession = u3DDbSessionMap.get(databaseName);
webSocketSession.sendMessage(new TextMessage("网页端尚未初始化,无法发送连接响应消息".getBytes()));
}
public void addU3DSession(String dbName, WebSocketSession session) {
u3DSession.put(dbName, session.getId());
}
public void addWebStatus(String sessionId, boolean status) {
webStatusMap.put(sessionId, status);
// unity端请求网页端连接或断开连接
public void sendUnityRequestConnectionMsg(String databaseName, String flag) throws IOException {
WebSocketSession webSession = getWebSession(databaseName);
JSONObject jsonObject = new JSONObject();
if ("1".equals(flag)) {
jsonObject.put("msgType", "unityRequestConnection");
jsonObject.put("unityConnectionFlag", "1");
webSession.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
setU3DStatus(databaseName, true);
}
if ("0".equals(flag)) {
jsonObject.put("msgType", "unityRequestConnection");
jsonObject.put("unityConnectionFlag", "0");
webSession.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
setU3DStatus(databaseName, false);
// 把网页端的sessionStatus置为false
setWebStatus(databaseName, false);
}
}
public void addU3DStatusMap(String sessionId, boolean status) {
webStatusMap.put(sessionId, status);
public WebSocketSession getUnitySession(String databaseName) {
return u3DDbSessionMap.getOrDefault(databaseName, null);
}
public void setU3DStatus(String dbName, boolean status) {
WebSocketSession webSocketSession = u3DDbSessionMap.get(dbName);
u3DStatusMap.put(webSocketSession, status);
}
public boolean getUnityConnectionStatus(String dbName) {
return u3DStatusMap.getOrDefault(u3DDbSessionMap.get(dbName),false);
}
// web端请求unity端连接或断开连接
public void sendWebRequestConnectionMsg(String databaseName, String flag) throws IOException {
WebSocketSession webSession = getWebSession(databaseName);
JSONObject jsonObject = new JSONObject();
if ("1".equals(flag)) {
jsonObject.put("msgType", "webRequestConnection");
jsonObject.put("webConnectionFlag", "1");
webSession.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
setWebStatus(databaseName,true);
}
if ("0".equals(flag)) {
jsonObject.put("msgType", "webRequestConnection");
jsonObject.put("webConnectionFlag", "0");
webSession.sendMessage(new TextMessage(jsonObject.toJSONString().getBytes()));
setU3DStatus(databaseName, false);
// 把网页端的sessionStatus置为false
setWebStatus(databaseName, false);
}
}
public void sendConnectionResponseToUnity(String databaseName, String flag) throws IOException {
WebSocketSession unitySession = getUnitySession(databaseName);
if (unitySession != null) {
JSONObject unityMsg = new JSONObject();
if ("1".equals(flag)) {
// 网页端同意连接
setWebStatus(databaseName, true);
unityMsg.put("msgType", "webResponseConnection");
unityMsg.put("webConnectionFlag", "1");
unitySession.sendMessage(new TextMessage(unityMsg.toJSONString().getBytes()));
}
if ("0".equals(flag)) {
// 网页端拒绝连接
setWebStatus(databaseName, false);
unityMsg = new JSONObject();
unityMsg.put("msgType", "connection refused");
unityMsg.put("webConnectionFlag", "0");
unitySession.sendMessage(new TextMessage(unityMsg.toJSONString().getBytes()));
// 把unity的sessionStatus置为false
setU3DStatus(databaseName, false);
}
} else {
// 告知网页端U3d尚未初始化
System.out.println("U3d尚未初始化无法发送连接响应消息");
WebSocketSession webSocketSession = webDbSessionMap.get(databaseName);
webSocketSession.sendMessage(new TextMessage("U3d尚未初始化无法发送连接响应消息".getBytes()));
}
}
public void setWebStatus(String dbName, Boolean status) {
WebSocketSession webSocketSession = webDbSessionMap.get(dbName);
webSessionStatusMap.put(webSocketSession, status);
}
public boolean getWebConnectionStatus(String dbName) {
return webSessionStatusMap.getOrDefault(webDbSessionMap.get(dbName),false);
}
public WebSocketSession getWebSession(String databaseName) {
webDbSessionMap.forEach((key, value) -> {
System.out.println("key = " + key + ", value = " + value);
});
return webDbSessionMap.getOrDefault(databaseName, null);
}
public void initWeb(String databaseName, WebSocketSession session, boolean b) {
webDbSessionMap.put(databaseName, session);
webSessionStatusMap.put(session, false);
}
public void initUnity(String databaseName, WebSocketSession session, WebSocketSession session1) {
u3DDbSessionMap.put(databaseName, session);
u3DStatusMap.put(session, false);
}
public boolean isReady(String databaseName) {
return getUnityConnectionStatus(databaseName) && getWebConnectionStatus(databaseName);
}
public void closeConnection(WebSocketSession session) {
webDbSessionMap.values().remove(session);
webSessionStatusMap.remove(session);
u3DDbSessionMap.values().remove(session);
u3DStatusMap.remove(session);
}
}