质控
This commit is contained in:
parent
bd9d44c5fb
commit
9cbe312933
@ -0,0 +1,50 @@
|
|||||||
|
package com.czlis.interfaceCommon.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.websocket.server.ServerEndpointConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 独立的WebSocket Spring上下文配置器
|
||||||
|
* 作用:解决WebSocket端点中获取Spring Bean的问题,替代过时的SpringConfigurator
|
||||||
|
* 适配:SpringBoot 2.x + 若依框架 + Tomcat 8/9/10
|
||||||
|
*/
|
||||||
|
@Component // 让Spring扫描并初始化该类,获取上下文
|
||||||
|
public class SpringContextWebSocketConfigurator extends ServerEndpointConfig.Configurator implements ApplicationContextAware {
|
||||||
|
|
||||||
|
// 静态持有Spring上下文(全局唯一)
|
||||||
|
private static ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实现ApplicationContextAware接口,Spring启动时自动注入上下文
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext context) throws BeansException {
|
||||||
|
// 仅初始化一次,避免多次赋值
|
||||||
|
if (applicationContext == null) {
|
||||||
|
applicationContext = context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重写创建端点实例的核心方法
|
||||||
|
* 从Spring容器中获取WebSocket端点实例,保证Bean注入生效
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
|
||||||
|
// 双重校验:上下文存在 + 容器中有该Bean
|
||||||
|
if (applicationContext != null) {
|
||||||
|
try {
|
||||||
|
return applicationContext.getBean(clazz);
|
||||||
|
} catch (BeansException e) {
|
||||||
|
// 容器中无该Bean时,降级使用默认实例化逻辑(兼容测试场景)
|
||||||
|
return super.getEndpointInstance(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 上下文未初始化时,走父类默认逻辑
|
||||||
|
return super.getEndpointInstance(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,7 +4,9 @@ import com.alibaba.fastjson2.JSON;
|
|||||||
import com.czlis.common.core.domain.model.LoginUser;
|
import com.czlis.common.core.domain.model.LoginUser;
|
||||||
import com.czlis.common.utils.SecurityUtils;
|
import com.czlis.common.utils.SecurityUtils;
|
||||||
import com.czlis.common.utils.spring.SpringUtils;
|
import com.czlis.common.utils.spring.SpringUtils;
|
||||||
|
import com.czlis.interfaceCommon.config.SpringContextWebSocketConfigurator;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.socket.server.standard.SpringConfigurator;
|
import org.springframework.web.socket.server.standard.SpringConfigurator;
|
||||||
|
|
||||||
import javax.websocket.*;
|
import javax.websocket.*;
|
||||||
@ -24,7 +26,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
* 工具方法暴露:在 WebSocket 端点类中提供静态工具方法(如 sendToUser、broadcast),其他业务直接调用该方法,无需关心实例创建;
|
* 工具方法暴露:在 WebSocket 端点类中提供静态工具方法(如 sendToUser、broadcast),其他业务直接调用该方法,无需关心实例创建;
|
||||||
* 避免重复连接:连接的创建 / 销毁由 WebSocket 协议自动管理(@OnOpen 新增、@OnClose 移除),业务层不干预实例创建。
|
* 避免重复连接:连接的创建 / 销毁由 WebSocket 协议自动管理(@OnOpen 新增、@OnClose 移除),业务层不干预实例创建。
|
||||||
*/
|
*/
|
||||||
@ServerEndpoint(value = "/ws/msgserver/{userId}", configurator = SpringConfigurator.class)
|
@Component
|
||||||
|
@ServerEndpoint(value = "/ws/msgserver/{userId}", configurator = SpringContextWebSocketConfigurator.class)
|
||||||
public class ChatWebSocketServer {
|
public class ChatWebSocketServer {
|
||||||
// 🌟 核心固定参数白名单:这些参数不存入动态属性(单独解析为固定身份属性)
|
// 🌟 核心固定参数白名单:这些参数不存入动态属性(单独解析为固定身份属性)
|
||||||
private static final Set<String> CORE_PARAMS = new HashSet<>(Arrays.asList("token", "username", "role"));
|
private static final Set<String> CORE_PARAMS = new HashSet<>(Arrays.asList("token", "username", "role"));
|
||||||
@ -94,22 +97,47 @@ public class ChatWebSocketServer {
|
|||||||
try {
|
try {
|
||||||
// 1. 基础校验:消息为空/连接关闭 → 直接返回
|
// 1. 基础校验:消息为空/连接关闭 → 直接返回
|
||||||
if (message == null || message.trim().isEmpty() || !session.isOpen()) {
|
if (message == null || message.trim().isEmpty() || !session.isOpen()) {
|
||||||
|
System.out.println("消息为空或连接已关闭,忽略处理:userId=" + userId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 解析消息为统一协议对象(JSON解析)
|
// 2. 前置校验:判断是否为合法JSON(避免非JSON字符串直接解析)
|
||||||
WebSocketMessage wsMessage = JSON.parseObject(message, WebSocketMessage.class);
|
String trimMsg = message.trim();
|
||||||
if (wsMessage == null) {
|
if (!isValidJson(trimMsg)) {
|
||||||
sendToUser(userId, "错误:消息格式不合法,请按JSON格式发送");
|
String errorMsg = "错误:消息格式必须是JSON字符串,当前消息:" + trimMsg;
|
||||||
|
sendToUser(userId, errorMsg);
|
||||||
|
System.out.println("非JSON消息被拒绝:userId=" + userId + ",消息=" + trimMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//暂时使用默认时间戳,生产环境应该使用客户端必传字段
|
|
||||||
|
// 3. 解析JSON为消息对象(捕获解析异常)
|
||||||
|
WebSocketMessage wsMessage;
|
||||||
|
try {
|
||||||
|
wsMessage = JSON.parseObject(trimMsg, WebSocketMessage.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
String errorMsg = "错误:JSON格式不合法,无法解析为WebSocketMessage,原因:" + e.getMessage();
|
||||||
|
sendToUser(userId, errorMsg);
|
||||||
|
System.out.println("JSON解析失败:userId=" + userId + ",消息=" + trimMsg + ",原因=" + e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 校验解析后的对象是否为空
|
||||||
|
if (wsMessage == null) {
|
||||||
|
String errorMsg = "错误:消息解析后为空,请检查JSON格式";
|
||||||
|
sendToUser(userId, errorMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 补充默认值(时间戳/发送者ID)
|
||||||
if (wsMessage.getTimestamp() == null || wsMessage.getTimestamp() == 0) {
|
if (wsMessage.getTimestamp() == null || wsMessage.getTimestamp() == 0) {
|
||||||
wsMessage.setTimestamp(System.currentTimeMillis());
|
wsMessage.setTimestamp(System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
// 3. 补充发送者ID(从路径参数获取,避免客户端伪造)
|
|
||||||
wsMessage.setSenderId(userId);
|
wsMessage.setSenderId(userId);
|
||||||
|
|
||||||
|
// 6. 生成唯一消息ID(避免重试队列重复)
|
||||||
|
if (wsMessage.getMsgId() == null || wsMessage.getMsgId().isEmpty()) {
|
||||||
|
wsMessage.setMsgId(userId + "_" + System.currentTimeMillis());
|
||||||
|
}
|
||||||
// 4. 获取Spring管理的业务层Bean,转发消息处理
|
// 4. 获取Spring管理的业务层Bean,转发消息处理
|
||||||
WebSocketMsgService msgService = SpringUtils.getBean(WebSocketMsgService.class);
|
WebSocketMsgService msgService = SpringUtils.getBean(WebSocketMsgService.class);
|
||||||
if (msgService == null) {
|
if (msgService == null) {
|
||||||
@ -190,7 +218,26 @@ public class ChatWebSocketServer {
|
|||||||
}
|
}
|
||||||
return roleUsers;
|
return roleUsers;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 根据登录IP筛选在线用户(精确匹配)
|
||||||
|
* @param loginIp 要查询的登录IP(如 "192.168.1.100")
|
||||||
|
* @return 匹配该IP的在线且连接有效的用户列表
|
||||||
|
*/
|
||||||
|
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()) {
|
||||||
|
ipUsers.add(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ipUsers;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 获取在线用户的userId列表(兼容原有逻辑)
|
* 获取在线用户的userId列表(兼容原有逻辑)
|
||||||
*/
|
*/
|
||||||
@ -291,5 +338,19 @@ public class ChatWebSocketServer {
|
|||||||
user.removeDynamicAttr(attrKey);
|
user.removeDynamicAttr(attrKey);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
private boolean isValidJson(String jsonStr) {
|
||||||
|
// 1. 先过滤空值,避免无意义解析
|
||||||
|
if (jsonStr == null || jsonStr.trim().isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 2. 核心:用 FastJSON2 解析为 JSON 对象/数组,解析成功则合法
|
||||||
|
JSON.parse(jsonStr);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 3. 解析失败(抛出 JSONException),说明非合法 JSON
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import lombok.NoArgsConstructor;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class WebSocketMessage {
|
public class WebSocketMessage {
|
||||||
|
private String msgId;
|
||||||
// 消息类型(如CHAT/NOTICE/ORDER/HEARTBEAT)
|
// 消息类型(如CHAT/NOTICE/ORDER/HEARTBEAT)
|
||||||
private String msgType;
|
private String msgType;
|
||||||
// 业务数据(JSON字符串,可解析为对应业务DTO)
|
// 业务数据(JSON字符串,可解析为对应业务DTO)
|
||||||
|
|||||||
@ -1,17 +1,11 @@
|
|||||||
package com.czlis.interfaceCommon.websocket;
|
package com.czlis.interfaceCommon.websocket;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.czlis.common.annotation.Async;
|
|
||||||
import com.czlis.common.core.redis.RedisCache;
|
import com.czlis.common.core.redis.RedisCache;
|
||||||
import com.czlis.common.utils.spring.SpringUtils;
|
import com.czlis.common.utils.spring.SpringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import javax.websocket.Session;
|
import javax.websocket.Session;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**业务层(Spring Bean)专注于「消息解析、权限校验、业务逻辑处理、结果推送」,支持不同类型消息的差异化处理。
|
/**业务层(Spring Bean)专注于「消息解析、权限校验、业务逻辑处理、结果推送」,支持不同类型消息的差异化处理。
|
||||||
@ -32,6 +26,7 @@ public class WebSocketMsgServiceImpl implements WebSocketMsgService {
|
|||||||
ChatWebSocketServer.sendToUser(wsMessage.getSenderId(), "提示:消息已处理,无需重复发送");
|
ChatWebSocketServer.sendToUser(wsMessage.getSenderId(), "提示:消息已处理,无需重复发送");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
System.err.println("wsMessage=" + wsMessage);
|
||||||
try {
|
try {
|
||||||
// 1. 基础校验:消息类型、发送者ID
|
// 1. 基础校验:消息类型、发送者ID
|
||||||
String msgType = wsMessage.getMsgType();
|
String msgType = wsMessage.getMsgType();
|
||||||
@ -170,22 +165,82 @@ public class WebSocketMsgServiceImpl implements WebSocketMsgService {
|
|||||||
private void handleHeartbeatMsg(WebSocketMessage wsMessage) {
|
private void handleHeartbeatMsg(WebSocketMessage wsMessage) {
|
||||||
String senderId = wsMessage.getSenderId();
|
String senderId = wsMessage.getSenderId();
|
||||||
// 回复心跳确认
|
// 回复心跳确认
|
||||||
ChatWebSocketServer.sendToUser(senderId, JSON.toJSONString(new WebSocketMessage("HEARTBEAT_ACK", "pong", senderId, null, System.currentTimeMillis())));
|
ChatWebSocketServer.sendToUser(senderId, JSON.toJSONString(new WebSocketMessage(senderId + "_" + System.currentTimeMillis(),"HEARTBEAT_ACK", "pong", senderId, null, System.currentTimeMillis())));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 示例3:给在线用户设置动态属性(如设备类型)
|
* 示例方法:给在线用户设置动态属性(如设备类型),优化后版本
|
||||||
*/
|
*/
|
||||||
public void setClientInfo(WebSocketMessage wsMessage) {
|
public void setClientInfo(WebSocketMessage wsMessage) {
|
||||||
|
// 1. 前置空值校验:避免空指针异常
|
||||||
|
if (wsMessage == null) {
|
||||||
|
System.err.println("setClientInfo失败:wsMessage为null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String senderId = wsMessage.getSenderId();
|
String senderId = wsMessage.getSenderId();
|
||||||
String data = wsMessage.getData();
|
String data = wsMessage.getData();
|
||||||
Map<String, Object> dataStrMap = JSON.parseObject(data, Map.class);
|
|
||||||
|
// 校验核心参数
|
||||||
|
if (senderId == null || senderId.trim().isEmpty()) {
|
||||||
|
System.err.println("setClientInfo失败:senderId为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data == null || data.trim().isEmpty()) {
|
||||||
|
System.err.println("setClientInfo失败:data为空,senderId=" + senderId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 安全解析JSON:捕获解析异常
|
||||||
|
Map<String, Object> dataStrMap;
|
||||||
|
try {
|
||||||
|
dataStrMap = JSON.parseObject(data, Map.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("setClientInfo失败:JSON解析异常,senderId=" + senderId + ",data=" + data + ",异常:" + e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 获取在线用户并校验有效性
|
||||||
WebSocketUser user = ChatWebSocketServer.getOnlineUser(senderId);
|
WebSocketUser user = ChatWebSocketServer.getOnlineUser(senderId);
|
||||||
if (user != null) {
|
if (user == null) {
|
||||||
|
System.err.println("setClientInfo失败:未找到在线用户,senderId=" + senderId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// // 额外校验连接是否有效
|
||||||
|
// if (!user.isConnected()) {
|
||||||
|
// System.err.println("setClientInfo失败:用户连接已关闭,senderId=" + senderId);
|
||||||
|
// // 可选:移除离线用户
|
||||||
|
// ChatWebSocketServer.removeOnlineUser(senderId);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 4. 遍历更新属性:优化判断逻辑,避免重复赋值
|
||||||
for (Map.Entry<String, Object> entry : dataStrMap.entrySet()) {
|
for (Map.Entry<String, Object> entry : dataStrMap.entrySet()) {
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
String value =(String)entry.getValue();
|
// 空值校验:避免key/value为null导致的异常
|
||||||
|
if (key == null || entry.getValue() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 统一转为字符串(兼容非字符串类型的value)
|
||||||
|
String value = String.valueOf(entry.getValue()).trim();
|
||||||
|
|
||||||
|
// 优先更新固定属性,再更新动态属性
|
||||||
|
switch (key) {
|
||||||
|
case "username":
|
||||||
|
user.setUsername(value);
|
||||||
|
break;
|
||||||
|
case "role":
|
||||||
|
user.setRole(value);
|
||||||
|
break;
|
||||||
|
case "loginIp":
|
||||||
|
user.setLoginIp(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 非固定属性,存入动态属性
|
||||||
user.setDynamicAttr(key, value);
|
user.setDynamicAttr(key, value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.out.println("setClientInfo成功:用户属性更新完成,senderId=" + senderId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
package com.czlis.interfaceCommon.websocket;
|
package com.czlis.interfaceCommon.websocket;
|
||||||
|
|
||||||
import javax.websocket.Session;
|
import javax.websocket.Session;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@ -10,12 +9,12 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
* 封装WebSocket用户连接信息:聚合Session + 身份属性 + 连接元数据
|
* 封装WebSocket用户连接信息:聚合Session + 身份属性 + 连接元数据
|
||||||
*/
|
*/
|
||||||
public class WebSocketUser {
|
public class WebSocketUser {
|
||||||
// 核心字段:用户唯一标识
|
// 核心字段:用户唯一标识(仍保持final,不建议修改)
|
||||||
private final String userId;
|
private final String userId;
|
||||||
// 身份属性(可根据业务扩展)
|
// 身份属性(移除final修饰符,支持修改)
|
||||||
private final String username; // 用户名
|
private String username; // 用户名
|
||||||
private final String role; // 角色(如ADMIN/USER)
|
private String role; // 角色(如ADMIN/USER)
|
||||||
private final String loginIp; // 登录IP
|
private String loginIp; // 登录IP
|
||||||
// 连接元数据
|
// 连接元数据
|
||||||
private final Session session; // WebSocket连接会话
|
private final Session session; // WebSocket连接会话
|
||||||
private final LocalDateTime connectTime; // 连接建立时间
|
private final LocalDateTime connectTime; // 连接建立时间
|
||||||
@ -38,18 +37,34 @@ public class WebSocketUser {
|
|||||||
return userId;
|
return userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== 可修改属性(getter + setter) ==========
|
||||||
public String getUsername() {
|
public String getUsername() {
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加username的setter方法
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
public String getRole() {
|
public String getRole() {
|
||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加role的setter方法
|
||||||
|
public void setRole(String role) {
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
public String getLoginIp() {
|
public String getLoginIp() {
|
||||||
return loginIp;
|
return loginIp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加loginIp的setter方法
|
||||||
|
public void setLoginIp(String loginIp) {
|
||||||
|
this.loginIp = loginIp;
|
||||||
|
}
|
||||||
|
|
||||||
public Session getSession() {
|
public Session getSession() {
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,8 +33,8 @@ public class DictController extends BaseController {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ComDictService comDictService;
|
private ComDictService comDictService;
|
||||||
@Autowired
|
// @Autowired
|
||||||
WebSocketInstrComm webSocketInstrComm;
|
// WebSocketInstrComm webSocketInstrComm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取字典列表
|
* 获取字典列表
|
||||||
@ -107,11 +107,11 @@ public class DictController extends BaseController {
|
|||||||
return comDictService.insertComDictList(comDictList, updateSupport);
|
return comDictService.insertComDictList(comDictList, updateSupport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("测试服务")
|
// @ApiOperation("测试服务")
|
||||||
@GetMapping("/test1")
|
// @GetMapping("/test1")
|
||||||
public Result test1(){
|
// public Result test1(){
|
||||||
String jsonStr = "{\"data\":\"1234\"}";
|
// String jsonStr = "{\"data\":\"1234\"}";
|
||||||
webSocketInstrComm.sendToAllClient(jsonStr);
|
// webSocketInstrComm.sendToAllClient(jsonStr);
|
||||||
return new Result("0","成功!");
|
// return new Result("0","成功!");
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@ import com.czlis.common.core.domain.Result;
|
|||||||
import com.czlis.common.core.domain.entity.lis.LabIntersendList;
|
import com.czlis.common.core.domain.entity.lis.LabIntersendList;
|
||||||
import com.czlis.common.core.domain.entity.lis.LabReqdetail;
|
import com.czlis.common.core.domain.entity.lis.LabReqdetail;
|
||||||
import com.czlis.common.core.domain.entity.lis.LabReqmain;
|
import com.czlis.common.core.domain.entity.lis.LabReqmain;
|
||||||
|
import com.czlis.common.utils.SecurityUtils;
|
||||||
|
import com.czlis.common.utils.ip.IpUtils;
|
||||||
import com.czlis.interfaceCommon.constants.LisinterfaceNameConstants;
|
import com.czlis.interfaceCommon.constants.LisinterfaceNameConstants;
|
||||||
import com.czlis.interfaceCommon.pojo.entity.ReportParam;
|
import com.czlis.interfaceCommon.pojo.entity.ReportParam;
|
||||||
import com.czlis.interfaceCommon.pojo.inter.GetReqInterface;
|
import com.czlis.interfaceCommon.pojo.inter.GetReqInterface;
|
||||||
@ -16,7 +18,10 @@ import com.czlis.interfaceCommon.utils.CommonUtil;
|
|||||||
import com.czlis.interfaceCommon.utils.LisInterfaceUtil;
|
import com.czlis.interfaceCommon.utils.LisInterfaceUtil;
|
||||||
import com.czlis.interfaceCommon.utils.LisUtil;
|
import com.czlis.interfaceCommon.utils.LisUtil;
|
||||||
import com.czlis.interfaceCommon.utils.ReportUtil;
|
import com.czlis.interfaceCommon.utils.ReportUtil;
|
||||||
|
import com.czlis.interfaceCommon.websocket.ChatWebSocketServer;
|
||||||
import com.czlis.interfaceCommon.websocket.WebSocketInstrComm;
|
import com.czlis.interfaceCommon.websocket.WebSocketInstrComm;
|
||||||
|
import com.czlis.interfaceCommon.websocket.WebSocketMessage;
|
||||||
|
import com.czlis.interfaceCommon.websocket.WebSocketUser;
|
||||||
import com.czlis.zycx.mapper.LabIntersendListMapper;
|
import com.czlis.zycx.mapper.LabIntersendListMapper;
|
||||||
import com.czlis.zycx.mapper.ZycxMapper;
|
import com.czlis.zycx.mapper.ZycxMapper;
|
||||||
import com.czlis.zycx.pojo.QuerySqdVO;
|
import com.czlis.zycx.pojo.QuerySqdVO;
|
||||||
@ -312,9 +317,26 @@ public class ZycxServiceImpl implements ZycxService {
|
|||||||
labIntersendList.setUserid(userId);
|
labIntersendList.setUserid(userId);
|
||||||
labIntersendList.setCreatedate(commonUtil.getCurrentTime());
|
labIntersendList.setCreatedate(commonUtil.getCurrentTime());
|
||||||
labIntersendListMapper.insert(labIntersendList);
|
labIntersendListMapper.insert(labIntersendList);
|
||||||
return new Result("0","打印成功!",guid);
|
WebSocketMessage wsMessage=new WebSocketMessage();
|
||||||
|
wsMessage.setMsgType("lisbarprint");
|
||||||
|
wsMessage.setData("lisbarprint://"+guid);
|
||||||
|
wsMessage.setSenderId(SecurityUtils.getUsername());
|
||||||
|
return sendprintmsg(JSONUtil.toJsonStr(wsMessage));
|
||||||
|
// return new Result("0","打印成功!",guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result sendprintmsg(String msg){
|
||||||
|
String ip= IpUtils.getIpAddr();
|
||||||
|
List<WebSocketUser> printUsers = ChatWebSocketServer.getOnlineUsersByLoginIp(ip);
|
||||||
|
if (printUsers.isEmpty()) {
|
||||||
|
System.out.println("当前客户端打印插件不在线");
|
||||||
|
return new Result("-1","当前客户端打印插件不在线");
|
||||||
|
}
|
||||||
|
WebSocketUser webSocketUser=printUsers.get(0);
|
||||||
|
ChatWebSocketServer.sendToUser(webSocketUser.getUserId(), msg);
|
||||||
|
System.out.println("已给客户端[" + webSocketUser.getUsername() + "]推送打印通知,IP:" + webSocketUser.getLoginIp());
|
||||||
|
return new Result("0","打印成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user