From 223951964b5981734172cdd666106dc678193179 Mon Sep 17 00:00:00 2001 From: zhaoyz <2@2.com> Date: Fri, 22 Mar 2024 17:33:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=8B=E6=9C=AF=E8=81=8A=E5=A4=A9=E5=AE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/rax/vital/config/WebSocketConfig.java | 14 ++-- .../rax/vital/datasource/MongoDBSource.java | 2 +- .../interceptor/WSChannelInterceptor.java | 5 ++ .../medicine/controller/ChatController.java | 38 +++++++++++ .../controller/MedicineController.java | 14 +--- .../vital/medicine/service/ChatService.java | 7 ++ .../service/impl/ChatServiceImpl.java | 67 +++++++++++++++++++ 7 files changed, 127 insertions(+), 20 deletions(-) create mode 100644 vital-signs/src/main/java/com/rax/vital/medicine/controller/ChatController.java create mode 100644 vital-signs/src/main/java/com/rax/vital/medicine/service/ChatService.java create mode 100644 vital-signs/src/main/java/com/rax/vital/medicine/service/impl/ChatServiceImpl.java diff --git a/vital-signs/src/main/java/com/rax/vital/config/WebSocketConfig.java b/vital-signs/src/main/java/com/rax/vital/config/WebSocketConfig.java index 09f1209..95287b7 100644 --- a/vital-signs/src/main/java/com/rax/vital/config/WebSocketConfig.java +++ b/vital-signs/src/main/java/com/rax/vital/config/WebSocketConfig.java @@ -19,18 +19,18 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/rax/chat", "/rax/ai-medicine", "/rax/doctor-medicine", "/rax/vital-signs", "/rax/SurgeryData") + registry.addEndpoint("/rax/chat", "/rax/SurgeryData") .setAllowedOrigins("*"); } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { - long [] heartbeat = {10000, 5000}; - ThreadPoolTaskScheduler te = new ThreadPoolTaskScheduler(); - te.setPoolSize(1); - te.setThreadNamePrefix("wss-heartbeat-thread-"); - te.initialize(); - registry.enableSimpleBroker("/topic").setTaskScheduler(te).setHeartbeatValue(heartbeat); + // 第一个值表示客户端发送心跳消息的间隔时间,第二个值表示服务端发送心跳消息的间隔时间 + long [] heartbeat = {60000, 60000}; + ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); + threadPoolTaskScheduler.initialize(); + registry.enableSimpleBroker("/topic").setTaskScheduler(threadPoolTaskScheduler).setHeartbeatValue(heartbeat); + registry.enableSimpleBroker("/topic"); registry.setApplicationDestinationPrefixes("/front"); registry.setUserDestinationPrefix("/topic/user"); } diff --git a/vital-signs/src/main/java/com/rax/vital/datasource/MongoDBSource.java b/vital-signs/src/main/java/com/rax/vital/datasource/MongoDBSource.java index f3f90dc..149e6ea 100644 --- a/vital-signs/src/main/java/com/rax/vital/datasource/MongoDBSource.java +++ b/vital-signs/src/main/java/com/rax/vital/datasource/MongoDBSource.java @@ -57,7 +57,7 @@ public class MongoDBSource { // 允许的最大连接数。 builder.maxSize(120); // 最小连接数。 - builder.minSize(10); + builder.minSize(1); // 池连接可以存活的最长时间。零值表示寿命没有限制。超过其生命周期的池连接将被关闭并在必要时由新连接替换 builder.maxConnectionLifeTime(0, TimeUnit.SECONDS); // 池连接的最大空闲时间。零值表示对空闲时间没有限制。超过其空闲时间的池连接将被关闭并在必要时由新连接替换 diff --git a/vital-signs/src/main/java/com/rax/vital/interceptor/WSChannelInterceptor.java b/vital-signs/src/main/java/com/rax/vital/interceptor/WSChannelInterceptor.java index 2c0a19f..14fed11 100644 --- a/vital-signs/src/main/java/com/rax/vital/interceptor/WSChannelInterceptor.java +++ b/vital-signs/src/main/java/com/rax/vital/interceptor/WSChannelInterceptor.java @@ -1,5 +1,6 @@ package com.rax.vital.interceptor; +import com.rax.vital.medicine.service.ChatService; import com.rax.vital.timer.VitalSignTimer; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -26,6 +27,9 @@ public class WSChannelInterceptor implements ChannelInterceptor { @Autowired private VitalSignTimer vitalSignTimer; + @Autowired + private ChatService chatService; + @Override public Message preSend(Message message, MessageChannel channel) { @@ -53,6 +57,7 @@ public class WSChannelInterceptor implements ChannelInterceptor { || StompCommand.UNSUBSCRIBE.equals(accessor.getCommand())) { String simpSessionId = (String) accessor.getHeader("simpSessionId"); vitalSignTimer.stopTimerTaskMongo(simpSessionId); + chatService.stopTimerTaskMongo(simpSessionId); } } return message; diff --git a/vital-signs/src/main/java/com/rax/vital/medicine/controller/ChatController.java b/vital-signs/src/main/java/com/rax/vital/medicine/controller/ChatController.java new file mode 100644 index 0000000..faca068 --- /dev/null +++ b/vital-signs/src/main/java/com/rax/vital/medicine/controller/ChatController.java @@ -0,0 +1,38 @@ +package com.rax.vital.medicine.controller; + +import com.alibaba.fastjson.JSONObject; +import com.rax.vital.medicine.service.ChatService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.security.access.AccessDeniedException; +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.stereotype.Controller; + +@Controller +public class ChatController { + + @Autowired + private ChatService chatService; + + @Autowired + private OAuth2AuthorizationService authorizationService; + + @MessageMapping("/sendMessage") + public void sendMessage(MessageHeaders messageHeaders, String body) { + JSONObject params = JSONObject.parseObject(body); + OAuth2Authorization authorization = authorizationService.findByToken(params.getString("token"), OAuth2TokenType.ACCESS_TOKEN); + if (authorization != null) { + String username = authorization.getPrincipalName(); + String simpSessionId = messageHeaders.get("simpSessionId", String.class); + String db = params.getString("db"); + String msg = params.getString("msg"); + chatService.sendMessage(db, username, simpSessionId, msg); + } else { + throw new AccessDeniedException("Access is denied"); + } + } + +} diff --git a/vital-signs/src/main/java/com/rax/vital/medicine/controller/MedicineController.java b/vital-signs/src/main/java/com/rax/vital/medicine/controller/MedicineController.java index afddf55..a649d52 100644 --- a/vital-signs/src/main/java/com/rax/vital/medicine/controller/MedicineController.java +++ b/vital-signs/src/main/java/com/rax/vital/medicine/controller/MedicineController.java @@ -1,8 +1,6 @@ package com.rax.vital.medicine.controller; import com.alibaba.fastjson.JSONObject; -import com.rax.vital.medicine.service.AIMedicineService; -import com.rax.vital.medicine.service.DoctorMedicineService; import com.rax.vital.timer.VitalSignTimer; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; @@ -14,26 +12,18 @@ import org.springframework.security.access.AccessDeniedException; 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.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.stereotype.Controller; /** * 用药 * * @date 2024.2.19 */ -@RestController -@RequestMapping("/medicine") +@Controller @Tag(description = "medicine", name = "人工和AI用药管理") @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) public class MedicineController { - @Autowired - private AIMedicineService aiMedicineService; - - @Autowired - private DoctorMedicineService doctorMedicineService; - @Autowired private VitalSignTimer vitalSignTimer; diff --git a/vital-signs/src/main/java/com/rax/vital/medicine/service/ChatService.java b/vital-signs/src/main/java/com/rax/vital/medicine/service/ChatService.java new file mode 100644 index 0000000..e8ecc2d --- /dev/null +++ b/vital-signs/src/main/java/com/rax/vital/medicine/service/ChatService.java @@ -0,0 +1,7 @@ +package com.rax.vital.medicine.service; + +public interface ChatService { + void sendMessage(String db, String username, String simpSessionId, String msg); + + void stopTimerTaskMongo(String simpSessionId); +} diff --git a/vital-signs/src/main/java/com/rax/vital/medicine/service/impl/ChatServiceImpl.java b/vital-signs/src/main/java/com/rax/vital/medicine/service/impl/ChatServiceImpl.java new file mode 100644 index 0000000..c746f6d --- /dev/null +++ b/vital-signs/src/main/java/com/rax/vital/medicine/service/impl/ChatServiceImpl.java @@ -0,0 +1,67 @@ +package com.rax.vital.medicine.service.impl; + +import cn.hutool.core.date.DateUtil; +import com.rax.vital.datasource.MongoDBSource; +import com.rax.vital.medicine.service.ChatService; +import org.bson.Document; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +@RefreshScope +@Service +public class ChatServiceImpl implements ChatService { + + @Autowired + private SimpMessagingTemplate simpMessagingTemplate; + + private static final Map datasourceMap = new HashMap<>(100); + + // MongoDB的地址 + @Value("${vital-sign.mongodb.host}") + private String mongoDBHost; + + // MongoDB的用户名 + @Value("${vital-sign.mongodb.username}") + private String mongoUsername; + + // MongoDB的用户的密码 + @Value("${vital-sign.mongodb.password}") + private String mongoPassword; + + @Override + public void sendMessage(String db, String username, String simpSessionId, String msg) { + MongoDBSource mongoDBSource = datasourceMap.get(simpSessionId); + if (mongoDBSource == null) { + mongoDBSource = new MongoDBSource(mongoDBHost, mongoPassword, mongoUsername, db); + datasourceMap.put(simpSessionId, mongoDBSource); + mongoDBSource.open(); + } + + MongoTemplate template = mongoDBSource.getTemplate(); + Document document = new Document(); + document.put("content", msg); + document.put("create_time", DateUtil.now()); + document.put("create_user", username); + document.put("deleted", 0); + document.put("revoked", 0); + template.insert(document, "t_chat"); + + simpMessagingTemplate.convertAndSendToUser(db, "/chatroomMessage", document); + } + + @Override + public synchronized void stopTimerTaskMongo(String simpSessionId) { + MongoDBSource mongoDBSource = datasourceMap.get(simpSessionId); + if (mongoDBSource != null) { + mongoDBSource.close(); + datasourceMap.remove(simpSessionId); + } + } +}