6 changed files with 262 additions and 1 deletions
-
14pom.xml
-
28src/main/java/com/iflytop/nuclear/config/WebSocketConfiguration.java
-
28src/main/java/com/iflytop/nuclear/config/WebSocketServerEndpointConfig.java
-
35src/main/java/com/iflytop/nuclear/handler/MessageHandler.java
-
4src/main/java/com/iflytop/nuclear/service/impl/CheckServiceImpl.java
-
154src/main/java/com/iflytop/nuclear/websocket/WebSocketServer.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(); |
|||
} |
|||
} |
@ -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> T getEndpointInstance(Class<T> clazz){ |
|||
return context.getBean(clazz); |
|||
} |
|||
|
|||
@Override |
|||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { |
|||
WebSocketServerEndpointConfig.context = applicationContext; |
|||
} |
|||
|
|||
} |
@ -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!"); |
|||
} |
|||
} |
|||
|
|||
} |
@ -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<String> allowedUsers = new HashSet<>(Arrays.asList("nuclear")); |
|||
|
|||
/** |
|||
* 当前在线连接数 |
|||
*/ |
|||
private static AtomicInteger onlineCount = new AtomicInteger(0); |
|||
|
|||
/** |
|||
* 用来存放每个客户端对应的 WebSocketServer 对象 |
|||
*/ |
|||
private static ConcurrentHashMap<String, WebSocketServer> 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(); |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue