SpringBoot整合WebSocket带案例

WebSocket通信过程

客户端构建一个websocket实例,并且为它绑定一个需要连接到的服务器地址,当客户端连接服务端的候,会向服务端发送一个http get报文,告诉服务端需要将通信协议切换到websocket,服务端收到http请求后将通信协议切换到websocket,同时发给客户端一个响应报文,返回的状态码为101,表示同意客户端协议转请求,并转换为websocket协议。以上过程都是利用http通信完成的,称之为websocket协议握手(websocket Protocol handshake),经过握手之后,客户端和服务端就建立了websocket连接,以后的通信走的都是websocket协议了。
 

1.pom文件

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

2.启动类上面

@SpringBootApplication
@EnableWebSocket
public class ServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceApplication.class);
    }
}

3.配置WebSocketConfig

@Configuration
@SuppressWarnings("all")
public class WebSocketConfig implements WebSocketConfigurer {
    @Autowired
    private TerminalInfoMapper terminalInfoMapper;
    @Autowired
    private TerminalGroupMapper terminalGroupMapper;
    @Autowired
    private FileEncryptionTypeMapper fileEncryptionTypeMapper;
    @Autowired
    private ProcessWhiteInfoMapper processWhiteInfoMapper;
    @Autowired
    private FeatureInfoMapper featureInfoMapper;
    @Autowired
    private CustomDirectoryMapper customDirectoryMapper;

    @Bean
    public TextWebSocketHandler textWebSocketHandler(){
        // 试过在MyWebSocketHandler类上加入@Component注解,然后Autoware注入mapper,但是不能成功,提示mapper为null
        return new MyWebSocketHandler(terminalInfoMapper, terminalGroupMapper, fileEncryptionTypeMapper, processWhiteInfoMapper, featureInfoMapper, customDirectoryMapper);
    }
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(textWebSocketHandler(), "/api/control/")
                //.addInterceptors(new WebSocketHandshakeInterceptor())
                .setAllowedOrigins("*");
    }
}

4.WebSocket处理类

因为WebSocket是类似客户端服务端的形式(采用ws协议),那么这里的WebSocketHandler其实就相当于一个ws协议的Controller将此类注册进WebSocketConfig中去,注意要采用@Bean的方式注入,不然Autoware引入其他bean的时候可能会出现空指针异常
下面是具体业务代码:

@Slf4j
@SuppressWarnings("all")
public class MyWebSocketHandler extends TextWebSocketHandler {
    // 统计在线人数
    public static AtomicLong atomicLong = new AtomicLong(0);
    // 分组
    public static final ConcurrentHashMap<WebSocketSession, String> CLIENTS = new ConcurrentHashMap<>();
    // VIP组
    public static final ConcurrentHashMap<WebSocketSession, String> VIP_CLIENTS = new ConcurrentHashMap<>();
    private TerminalInfoMapper terminalInfoMapper;
    private TerminalGroupMapper terminalGroupMapper;
    private FileEncryptionTypeMapper fileEncryptionTypeMapper;
    private ProcessWhiteInfoMapper processWhiteInfoMapper;
    private FeatureInfoMapper featureInfoMapper;
    private CustomDirectoryMapper customDirectoryMapper;

    @Autowired
    private WebsocketUtil websocketUtil;

    public MyWebSocketHandler() {
    }

    public MyWebSocketHandler(TerminalInfoMapper terminalInfoMapper,
                              TerminalGroupMapper terminalGroupMapper,
                              FileEncryptionTypeMapper fileEncryptionTypeMapper,
                              ProcessWhiteInfoMapper processWhiteInfoMapper,
                              FeatureInfoMapper featureInfoMapper,
                              CustomDirectoryMapper customDirectoryMapper) {
        this.terminalInfoMapper = terminalInfoMapper;
        this.terminalGroupMapper = terminalGroupMapper;
        this.fileEncryptionTypeMapper = fileEncryptionTypeMapper;
        this.processWhiteInfoMapper = processWhiteInfoMapper;
        this.featureInfoMapper = featureInfoMapper;
        this.customDirectoryMapper = customDirectoryMapper;
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
//        WebsocketUtil websocketUtil = new WebsocketUtil();
        URI uri = session.getUri();
        String query = uri.getQuery();
        System.out.println("query = " + query);
        Map<String, String> queryMap = websocketUtil.queryValue(query);
        System.out.println("queryMap = " + queryMap);
        if (queryMap == null || queryMap.get("terminal_id") == null){
            session.close();
        }
        websocketUtil.dealTerminal(session, queryMap.get("terminal_id"), terminalInfoMapper, terminalGroupMapper, featureInfoMapper, fileEncryptionTypeMapper, processWhiteInfoMapper, customDirectoryMapper);
        System.out.println("query = " + query);
        System.out.println("uri = " + uri);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        CLIENTS.remove(session);
        if (VIP_CLIENTS.containsKey(session)) VIP_CLIENTS.remove(session);
        log.info("终端{}\t退出连接", CLIENTS.get(session));
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        log.info("收到的消息是!{}", message.getPayload().toString());
//        WebsocketUtil websocketUtil = new WebsocketUtil();
        websocketUtil.send(session, message);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        CLIENTS.remove(session);
        if (VIP_CLIENTS.containsKey(session)) VIP_CLIENTS.remove(session);
        log.error("终端{}\t发生错误{}", CLIENTS.get(session), exception.getMessage());
    }
}

5.WebSocketUtil

@Slf4j
@Component
@SuppressWarnings("all")
public class WebsocketUtil {
    public Map<String, String> queryValue(String uri){
        if (uri != null){
            System.out.println("uri = " + uri);
            String[] paramsArray = uri.split("&");
            System.out.println("paramsArray = " + Arrays.toString(paramsArray));
            if (paramsArray.length > 0) {
                for (String s : paramsArray) {
                    String[] strings = s.split("=");
                    return dealParams(strings);
                }
            }
        }
        return null;
    }

    private Map<String, String> dealParams(String[] paramsArray) {
        Map<String, String> map = new HashMap<>();
        for (int i = 0; i < paramsArray.length; i = i + 2) {
            switch (paramsArray[i]){
                case "terminal_id" -> map.put("terminal_id", paramsArray[i + 1].replace("&", ""));
                case "virus_version" -> map.put("virus_version", paramsArray[i + 1].replace("&", ""));
                case "edr_version" -> map.put("edr_version", paramsArray[i + 1].replace("&", ""));
                case "scanner_version" -> map.put("scanner_version", paramsArray[i + 1].replace("&", ""));
            }
        }
        return map;
    }

    public void dealTerminal(WebSocketSession session,
                             String terminal_id,
                             TerminalInfoMapper terminalInfoMapper,
                             TerminalGroupMapper terminalGroupMapper,
                             FeatureInfoMapper featureInfoMapper,
                             FileEncryptionTypeMapper fileEncryptionTypeMapper,
                             ProcessWhiteInfoMapper processWhiteInfoMapper,
                             CustomDirectoryMapper customDirectoryMapper) throws IOException {
        System.out.println("terminalInfoMapper = " + terminalInfoMapper);
        TerminalInfo terminalInfo = terminalInfoMapper.selectByTerminalId(terminal_id);
        if (terminalInfo == null){
            log.error("该客户端的mac地址不存在 {}", terminal_id);
            session.close();
            return;
        }
        List<FeatureInfo> featureInfoList = featureInfoMapper.selectAll();
        send(session, featureInfoList);

        List<FileEncryptionType> fileEncryptionTypes = fileEncryptionTypeMapper.selectAll();
        send(session, fileEncryptionTypes);

        List<String> processWhiteInfos = processWhiteInfoMapper.selectAll();
        send(session, processWhiteInfos);

        String groupId = terminalInfo.getGroup();
        if (groupId == "") groupId = null;
        TerminalGroup terminalGroup = terminalGroupMapper.selectByPrimaryKey(Long.valueOf(groupId));
        List<Map<String, Object>> maps = new ArrayList<>();
        Map<String, Object> vip = new HashMap<>();
        vip.put("Vip", false);
        maps.add(vip);
        if (terminalGroup != null){
            String groupName = terminalGroup.getGroupName();
            if (groupName == "Vip"){
                maps.get(0).put("Vip", true);
                List<CustomDirectory> customDirectories = customDirectoryMapper.selectAll();
                List<Object> list = new ArrayList<>();
                list.addAll(maps);
                list.addAll(customDirectories);
                MyWebSocketHandler.VIP_CLIENTS.put(session, terminal_id);
                System.out.println("MyWebSocketHandler.VIP_CLIENTS = " + MyWebSocketHandler.VIP_CLIENTS);
                send(session, list);
            }
        }
        MyWebSocketHandler.CLIENTS.put(session, terminal_id);
    }

    public synchronized void send(WebSocketSession session, Object feature_data) throws IOException {
        String message = null;
        String customDirector = JsonUtils.toStr(feature_data);
        session.sendMessage(new TextMessage(customDirector));
    }
}

6.测试如下

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值