Merge remote-tracking branch 'lis8.0/master'
This commit is contained in:
commit
93c7e5b140
@ -33,6 +33,7 @@ public class ChatWebSocketServer {
|
||||
private static final Set<String> CORE_PARAMS = new HashSet<>(Arrays.asList("token", "username", "role"));
|
||||
// 🌟 容器改为存储封装后的WebSocketUser(key=userId)
|
||||
private static final Map<String, WebSocketUser> ONLINE_USER_MAP = new ConcurrentHashMap<>();
|
||||
private static final Map<String, String> IP_TO_USERS_MAP = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* 连接建立时:封装用户信息并存入容器
|
||||
* 注意:若需要传递username/role等属性,可通过路径参数/请求参数/Token解析
|
||||
@ -79,6 +80,9 @@ public class ChatWebSocketServer {
|
||||
}
|
||||
// 5. 存入全局容器
|
||||
ONLINE_USER_MAP.put(userId, webSocketUser);
|
||||
if(loginIp!=null&&!"".equals(loginIp)&&userId!=null&&!"".equals(userId)&&!"未知IP".equals(loginIp)){
|
||||
updateIpIndex(loginIp,userId);
|
||||
}
|
||||
System.out.println("用户[" + userId + "-" + username + "]连接成功,IP:" + loginIp + ",当前在线人数:" + ONLINE_USER_MAP.size());
|
||||
}
|
||||
// ========== 消息接收核心方法 ==========
|
||||
@ -166,6 +170,7 @@ public class ChatWebSocketServer {
|
||||
@OnClose
|
||||
public void onClose(@PathParam("userId") String userId, Session session) {
|
||||
ONLINE_USER_MAP.remove(userId);
|
||||
ChatWebSocketServer.removeUserAllIpIndex(userId);
|
||||
System.out.println("用户[" + userId + "]断开连接,当前在线人数:" + ONLINE_USER_MAP.size());
|
||||
}
|
||||
|
||||
@ -176,6 +181,7 @@ public class ChatWebSocketServer {
|
||||
public void onError(@PathParam("userId") String userId, Session session, Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
ONLINE_USER_MAP.remove(userId);
|
||||
ChatWebSocketServer.removeUserAllIpIndex(userId);
|
||||
}
|
||||
|
||||
// ========== 工具方法:获取客户端IP ==========
|
||||
@ -188,7 +194,38 @@ public class ChatWebSocketServer {
|
||||
return "未知IP";
|
||||
}
|
||||
}
|
||||
// 1. 用户上线/修改IP时,更新索引(新增/覆盖)
|
||||
public static void updateIpIndex(String loginIp, String userId) {
|
||||
if (loginIp == null || loginIp.trim().isEmpty() || userId == null) {
|
||||
return;
|
||||
}
|
||||
IP_TO_USERS_MAP.put(loginIp.trim(), userId); // 唯一IP直接覆盖,保证最新
|
||||
}
|
||||
|
||||
// 2. 用户下线/IP失效时,删除索引
|
||||
public static void removeIpIndex(String loginIp) {
|
||||
if (loginIp == null || loginIp.trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
IP_TO_USERS_MAP.remove(loginIp.trim());
|
||||
}
|
||||
// ========== 3. 新增:批量删除某用户的所有IP索引(核心,供外部调用) ==========
|
||||
public static void removeUserAllIpIndex(String userId) {
|
||||
if (userId == null || userId.trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// 步骤1:收集该用户对应的所有IP
|
||||
List<String> userIps = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : IP_TO_USERS_MAP.entrySet()) {
|
||||
if (userId.equals(entry.getValue())) {
|
||||
userIps.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
// 步骤2:批量删除这些IP的索引
|
||||
for (String ip : userIps) {
|
||||
IP_TO_USERS_MAP.remove(ip);
|
||||
}
|
||||
}
|
||||
// ========== 🌟 暴露属性查询方法(业务层调用) ==========
|
||||
|
||||
/**
|
||||
@ -218,6 +255,15 @@ public class ChatWebSocketServer {
|
||||
}
|
||||
return roleUsers;
|
||||
}
|
||||
/**
|
||||
* 新增:通过IP快速查询对应的userId(核心效率方法)
|
||||
*/
|
||||
public static String getUserIdByIp(String ip) {
|
||||
if (ip == null || ip.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return IP_TO_USERS_MAP.get(ip.trim());
|
||||
}
|
||||
/**
|
||||
* 根据登录IP筛选在线用户(精确匹配)
|
||||
* @param loginIp 要查询的登录IP(如 "192.168.1.100")
|
||||
@ -225,17 +271,24 @@ public class ChatWebSocketServer {
|
||||
*/
|
||||
public static List<WebSocketUser> getOnlineUsersByLoginIp(String loginIp) {
|
||||
List<WebSocketUser> ipUsers = new ArrayList<>();
|
||||
// 前置空值校验:避免传入null/空字符串导致无效查询
|
||||
// 前置空值校验
|
||||
if (loginIp == null || loginIp.trim().isEmpty()) {
|
||||
return ipUsers;
|
||||
}
|
||||
// 遍历在线用户,筛选匹配IP且连接有效的用户
|
||||
for (WebSocketUser user : ONLINE_USER_MAP.values()) {
|
||||
// 双重校验:IP精确匹配 + 连接有效
|
||||
if (loginIp.equals(user.getLoginIp()) && user.isConnected()) {
|
||||
|
||||
// 核心改造:直接从索引Map拿userId,无需遍历!
|
||||
String userId = IP_TO_USERS_MAP.get(loginIp.trim());
|
||||
// 没找到userId,直接返回空
|
||||
if (userId == null) {
|
||||
return ipUsers;
|
||||
}
|
||||
|
||||
// 找到userId后,查用户+校验连接有效性
|
||||
WebSocketUser user = ONLINE_USER_MAP.get(userId);
|
||||
if (user != null && user.isConnected()) {
|
||||
ipUsers.add(user);
|
||||
}
|
||||
}
|
||||
|
||||
return ipUsers;
|
||||
}
|
||||
/**
|
||||
|
||||
@ -14,7 +14,7 @@ import java.util.Collection;
|
||||
/**
|
||||
* ws仪器通讯类
|
||||
*/
|
||||
@Component
|
||||
//@Component
|
||||
@ServerEndpoint("/ws/instr/{sid}")
|
||||
public class WebSocketInstrComm extends WebSocketServer {
|
||||
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
package com.czlis.interfaceCommon.websocket;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.czlis.common.core.redis.RedisCache;
|
||||
import com.czlis.common.utils.spring.SpringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import javax.websocket.Session;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -232,7 +235,10 @@ public class WebSocketMsgServiceImpl implements WebSocketMsgService {
|
||||
user.setRole(value);
|
||||
break;
|
||||
case "loginIp":
|
||||
user.setLoginIp(value);
|
||||
// 关键:更新loginIp时,先删旧IP索引,再加新IP索引
|
||||
ChatWebSocketServer.removeIpIndex(user.getLoginIp()); // 删旧IP
|
||||
user.setLoginIp(value); // 更IP
|
||||
ChatWebSocketServer.updateIpIndex(value, senderId); // 加新IP
|
||||
break;
|
||||
default:
|
||||
// 非固定属性,存入动态属性
|
||||
@ -240,7 +246,76 @@ public class WebSocketMsgServiceImpl implements WebSocketMsgService {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 新增:解析并添加多IP列表
|
||||
this.addIpList(dataStrMap,senderId);
|
||||
System.out.println("setClientInfo成功:用户属性更新完成,senderId=" + senderId);
|
||||
}
|
||||
/**
|
||||
* 解析客户端传递的多IP列表,并同步更新IP→userId索引
|
||||
* 核心逻辑:先清理该用户所有旧IP索引 → 再添加新IP索引,避免索引残留/冗余
|
||||
* @param dataStrMap 解析后的客户端JSON数据Map
|
||||
* @param userId 当前操作的用户ID(非空)
|
||||
*/
|
||||
public void addIpList(Map<String, Object> dataStrMap, String userId) {
|
||||
// 1. 第一层空值校验:数据Map/用户ID为空直接返回
|
||||
if (dataStrMap == null || userId == null || userId.trim().isEmpty()) {
|
||||
System.err.println("addIpList失败:dataStrMap为空 或 userId为空");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 第二层空值校验:iplist字段为空直接返回
|
||||
Object ipListObj = dataStrMap.get("iplist");
|
||||
if (ipListObj == null) {
|
||||
System.err.println("addIpList失败:userId=" + userId + ",iplist字段为空");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 3. 兼容iplist字段的两种格式:JSON字符串/JSON对象
|
||||
String ipListJson = ipListObj instanceof String ? (String) ipListObj : JSON.toJSONString(ipListObj);
|
||||
// 空JSON字符串直接返回
|
||||
if (ipListJson.trim().isEmpty()) {
|
||||
System.err.println("addIpList失败:userId=" + userId + ",iplist字段值为空字符串");
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 解析iplist为JSON对象
|
||||
JSONObject ipListJsonObj = JSON.parseObject(ipListJson);
|
||||
// 空JSON对象直接返回
|
||||
if (ipListJsonObj.isEmpty()) {
|
||||
System.err.println("addIpList失败:userId=" + userId + ",iplist字段值为空JSON对象");
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. 核心步骤1:清理该用户的所有旧IP索引(避免残留)
|
||||
ChatWebSocketServer.removeUserAllIpIndex(userId);
|
||||
|
||||
// 6. 核心步骤2:遍历新IP列表,同步到索引(自动去重+空值过滤)
|
||||
int validIpCount = 0; // 统计有效IP数量
|
||||
for (Object ipValue : ipListJsonObj.values()) {
|
||||
// 过滤null值
|
||||
if (ipValue == null) {
|
||||
continue;
|
||||
}
|
||||
// 转为字符串并去除首尾空格
|
||||
String ip = String.valueOf(ipValue).trim();
|
||||
// 过滤空IP字符串
|
||||
if (ip.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
// 同步到IP→userId索引
|
||||
ChatWebSocketServer.updateIpIndex(ip, userId);
|
||||
validIpCount++;
|
||||
}
|
||||
|
||||
// 7. 日志反馈:便于排查问题
|
||||
System.out.println("addIpList成功:userId=" + userId + ",清理旧IP索引并新增" + validIpCount + "个有效IP索引");
|
||||
|
||||
} catch (Exception e) {
|
||||
// 8. 异常捕获:细化异常信息,便于定位问题
|
||||
System.err.println("addIpList失败:userId=" + userId + ",iplist解析异常,异常信息:" + e.getMessage());
|
||||
// 可选:打印异常栈,便于调试
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,4 +90,5 @@ public class WebSocketUser {
|
||||
public boolean isConnected() {
|
||||
return session != null && session.isOpen();
|
||||
}
|
||||
|
||||
}
|
||||
@ -118,5 +118,17 @@ public class ZycxController extends BaseController {
|
||||
return zycxService.printSendSample(sqhArray);
|
||||
}
|
||||
|
||||
@Anonymous
|
||||
@ApiOperation("打印机插件设置")
|
||||
@GetMapping("/printsetup")
|
||||
public Result printsetup() {
|
||||
return zycxService.printsetup();
|
||||
}
|
||||
@Anonymous
|
||||
@ApiOperation("打印机插件检查")
|
||||
@GetMapping("/printcheck")
|
||||
public Result printcheck() {
|
||||
return zycxService.printcheck();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ public interface ZycxService {
|
||||
Result getSQDMain(LabReqmain labReqmain);
|
||||
|
||||
Result test1(String sqh);
|
||||
|
||||
Result printsetup();
|
||||
Result printcheck();
|
||||
Result printSendSample(String[] sqhList);
|
||||
}
|
||||
|
||||
@ -327,6 +327,7 @@ public class ZycxServiceImpl implements ZycxService {
|
||||
|
||||
public Result sendprintmsg(String msg){
|
||||
String ip= IpUtils.getIpAddr();
|
||||
System.out.println("请求业务的IP:"+ip);
|
||||
List<WebSocketUser> printUsers = ChatWebSocketServer.getOnlineUsersByLoginIp(ip);
|
||||
if (printUsers.isEmpty()) {
|
||||
System.out.println("当前客户端打印插件不在线");
|
||||
@ -337,6 +338,21 @@ public class ZycxServiceImpl implements ZycxService {
|
||||
System.out.println("已给客户端[" + webSocketUser.getUsername() + "]推送打印通知,IP:" + webSocketUser.getLoginIp());
|
||||
return new Result("0","打印成功");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Result printsetup(){
|
||||
WebSocketMessage wsMessage=new WebSocketMessage();
|
||||
wsMessage.setMsgType("lisbarprint");
|
||||
wsMessage.setData("lisbarprint://setup");
|
||||
wsMessage.setSenderId(SecurityUtils.getUsername());
|
||||
return sendprintmsg(JSONUtil.toJsonStr(wsMessage));
|
||||
}
|
||||
@Override
|
||||
public Result printcheck(){
|
||||
String ip= IpUtils.getIpAddr();
|
||||
String UserId = ChatWebSocketServer.getUserIdByIp(ip);
|
||||
if(UserId==null||"".equals(UserId)){
|
||||
return new Result("-1","当前客户端打印插件不在线或未安装");
|
||||
}
|
||||
return new Result("0","客户端插件正常");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user