From ea97c03abe125ba55186a83edb93ad56356953fd Mon Sep 17 00:00:00 2001 From: maochaoying <925670706@qq.com> Date: Mon, 3 Jul 2023 09:44:16 +0800 Subject: [PATCH] websocket --- pom.xml | 14 ++ .../nuclear/config/WebSocketConfiguration.java | 28 ++++ .../config/WebSocketServerEndpointConfig.java | 28 ++++ .../iflytop/nuclear/handler/MessageHandler.java | 35 +++++ .../nuclear/service/impl/CheckServiceImpl.java | 4 +- .../iflytop/nuclear/websocket/WebSocketServer.java | 154 +++++++++++++++++++++ 6 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/iflytop/nuclear/config/WebSocketConfiguration.java create mode 100644 src/main/java/com/iflytop/nuclear/config/WebSocketServerEndpointConfig.java create mode 100644 src/main/java/com/iflytop/nuclear/handler/MessageHandler.java create mode 100644 src/main/java/com/iflytop/nuclear/websocket/WebSocketServer.java diff --git a/pom.xml b/pom.xml index a90ec89..4ae6751 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,20 @@ true + org.springframework.boot + spring-boot-starter-websocket + + + com.alibaba + fastjson + 1.2.83 + + + javax.websocket + javax.websocket-api + 1.1 + + com.mysql mysql-connector-j 8.0.33 diff --git a/src/main/java/com/iflytop/nuclear/config/WebSocketConfiguration.java b/src/main/java/com/iflytop/nuclear/config/WebSocketConfiguration.java new file mode 100644 index 0000000..111b5b1 --- /dev/null +++ b/src/main/java/com/iflytop/nuclear/config/WebSocketConfiguration.java @@ -0,0 +1,28 @@ +package com.iflytop.nuclear.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @author cool + * @desc 注册配置类 将ServerEndpointExporter注册为bean + */ +@Configuration +@EnableWebSocket +public class WebSocketConfiguration { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + + /** + * 支持注入其他接口类 + */ + @Bean + public WebSocketServerEndpointConfig newWebSocketEndpointConfigure (){ + return new WebSocketServerEndpointConfig(); + } +} \ No newline at end of file diff --git a/src/main/java/com/iflytop/nuclear/config/WebSocketServerEndpointConfig.java b/src/main/java/com/iflytop/nuclear/config/WebSocketServerEndpointConfig.java new file mode 100644 index 0000000..6332a7f --- /dev/null +++ b/src/main/java/com/iflytop/nuclear/config/WebSocketServerEndpointConfig.java @@ -0,0 +1,28 @@ +package com.iflytop.nuclear.config; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +import javax.websocket.server.ServerEndpointConfig; + +/** + * @author cool + * @date 2023/4/26 21:18 + * @desc 解决websocketServer中 无法注入的问题 + */ +public class WebSocketServerEndpointConfig extends ServerEndpointConfig.Configurator implements ApplicationContextAware { + private static volatile BeanFactory context; + + @Override + public T getEndpointInstance(Class clazz){ + return context.getBean(clazz); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + WebSocketServerEndpointConfig.context = applicationContext; + } + +} \ No newline at end of file diff --git a/src/main/java/com/iflytop/nuclear/handler/MessageHandler.java b/src/main/java/com/iflytop/nuclear/handler/MessageHandler.java new file mode 100644 index 0000000..40c642a --- /dev/null +++ b/src/main/java/com/iflytop/nuclear/handler/MessageHandler.java @@ -0,0 +1,35 @@ +package com.iflytop.nuclear.handler; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.websocket.Session; +import java.io.IOException; + +/** + * @author cool + * @desc 根据不同的消息command分发到不同的handler中 + */ +@Component +@Slf4j +public class MessageHandler { + + /** + * dispatcher分发器 + * @param command 硬件端传来的commad字段 + * @param data 整体包数据 + * @param session websocket 连接会话 + */ + public void dispatcher(String command, JSONObject data, Session session) throws IOException { + switch (command){ + case "cmd1": + session.getBasicRemote().sendText("123"); + System.out.println(123); + break; + default: + System.out.println("No match!"); + } + } + +} diff --git a/src/main/java/com/iflytop/nuclear/service/impl/CheckServiceImpl.java b/src/main/java/com/iflytop/nuclear/service/impl/CheckServiceImpl.java index 520cd30..5b2359c 100644 --- a/src/main/java/com/iflytop/nuclear/service/impl/CheckServiceImpl.java +++ b/src/main/java/com/iflytop/nuclear/service/impl/CheckServiceImpl.java @@ -53,7 +53,8 @@ public class CheckServiceImpl implements CheckService { // 检测下一个坐标 while // 如果中间终止 则退出返回 // 下一次进入后则进入其他流程 - + String nextCoord = this.getNextCoord("1-6", 0); + System.out.println(nextCoord); // !!! 记录规则路径上的路过但是不检测的坐标 进行排除即可 }else { @@ -174,6 +175,7 @@ public class CheckServiceImpl implements CheckService { } } } + // 纵向 if (order == 1) { if (mainLine == 1) { diff --git a/src/main/java/com/iflytop/nuclear/websocket/WebSocketServer.java b/src/main/java/com/iflytop/nuclear/websocket/WebSocketServer.java new file mode 100644 index 0000000..bd880af --- /dev/null +++ b/src/main/java/com/iflytop/nuclear/websocket/WebSocketServer.java @@ -0,0 +1,154 @@ +package com.iflytop.nuclear.websocket; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.iflytop.nuclear.config.WebSocketServerEndpointConfig; +import com.iflytop.nuclear.handler.MessageHandler; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.NamedBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author cool + * @date 2023/4/26 19:31 + * @desc websocket server + */ +@ServerEndpoint(value = "/websocket/{userId}", configurator = WebSocketServerEndpointConfig.class) +@Component +@Slf4j +public class WebSocketServer { + + @Autowired + MessageHandler messageHandler; + + /** + * 仅允许某个userid进行连接, 指定该机器的macid + */ + private static Set allowedUsers = new HashSet<>(Arrays.asList("nuclear")); + + /** + * 当前在线连接数 + */ + private static AtomicInteger onlineCount = new AtomicInteger(0); + + /** + * 用来存放每个客户端对应的 WebSocketServer 对象 + */ + private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>(); + + /** + * 与某个客户端的连接会话,需要通过它来给客户端发送数据 + */ + private Session session; + + /** + * 接收 userId + */ + private String userId = ""; + + /** + * 连接建立成功调用的方法 + */ + @OnOpen + public void onOpen(Session session, @PathParam("userId") String userId) throws IOException { + if (!allowedUsers.contains(userId)) { + session.close(); + return; + } + this.session = session; + this.userId = userId; + if (webSocketMap.containsKey(userId)) { + webSocketMap.remove(userId); + webSocketMap.put(userId, this); + } else { + webSocketMap.put(userId, this); + addOnlineCount(); + } + log.info("用户连接:" + userId + ",当前在线人数为:" + getOnlineCount()); + try { + sendMessage("连接成功!"); + } catch (IOException e) { + log.error("用户:" + userId + ",网络异常!!!!!!"); + } + } + + /** + * 连接关闭调用的方法 + */ + @OnClose + public void onClose() { + if (webSocketMap.containsKey(userId)) { + webSocketMap.remove(userId); + subOnlineCount(); + } + log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount()); + } + + /** + * 收到客户端消息后调用的方法 + * + * @param message 客户端发送过来的消息 + */ + @OnMessage + public void onMessage(String message, Session session) throws IOException { + log.info("用户消息:" + userId + ",报文:" + message); + if (!StringUtils.isEmpty(message)) { + try { + JSONObject jsonObject = JSON.parseObject(message); + String command = jsonObject.getString("command"); + // 根据command类型,分发给不同的handler和detection + if (!command.isEmpty()) { + messageHandler.dispatcher(command, jsonObject, session); + } + } catch (Exception e) { + JSONObject msg = new JSONObject(); + msg.put("message", "传输数据必须为包含command字段的JSON格式"); + session.getBasicRemote().sendText(msg.toString()); + e.printStackTrace(); + } + } + } + + /** + * 发生错误时调用 + * + * @param session + * @param error + */ + @OnError + public void onError(Session session, Throwable error) { + log.error("用户错误:" + this.userId + ",原因:" + error.getMessage()); + error.printStackTrace(); + } + + /** + * 实现服务器主动推送 + */ + public void sendMessage(String message) throws IOException { + this.session.getBasicRemote().sendText(message); + } + + public static synchronized AtomicInteger getOnlineCount() { + return onlineCount; + } + + public static synchronized void addOnlineCount() { + WebSocketServer.onlineCount.getAndIncrement(); + } + + public static synchronized void subOnlineCount() { + WebSocketServer.onlineCount.getAndDecrement(); + } +} \ No newline at end of file