栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

若依springcloud gateway nacos 集成websocket

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

若依springcloud gateway nacos 集成websocket

一.代码部分

相应模块里面添加3个类

WebSocketConfig,MyWebSocketHandler,WebSocketInterceptor

1.WebSocketConfig

package com.ruoyi.config;

import com.ruoyi.handler.MyWebSocketHandler;
import com.ruoyi.interceptor.WebSocketInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;


@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    private static final Logger log = LoggerFactory.getLogger(WebSocketConfig.class);

    @Autowired
    private MyWebSocketHandler myWebSocketHandler;

    @Autowired
    private WebSocketInterceptor webSocketInterceptor;

    @Value("#{'${websocket.wsHandlers}'.split(',')}")
    private String[] paths;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myWebSocketHandler, paths)
                .setAllowedOrigins("*")
                .addInterceptors(webSocketInterceptor);
    }
}

2. MyWebSocketHandler

package com.ruoyi.handler;

import com.ruoyi.common.WebSocketCommon;
import com.ruoyi.common.core.constant.WebSocketConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;

@Component
public class MyWebSocketHandler implements WebSocketHandler {

    private static final Logger log = LoggerFactory.getLogger(MyWebSocketHandler.class);

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        log.info("connect websocket successful!");
        Object userId = session.getAttributes().get(WebSocketConstants.TOKEN);
        if(userId==null){
            return;
        }
        WebSocketSession oldSession = WebSocketCommon.CLIENT_SESSION.get(WebSocketCommon.getMapKey(session));
        if (oldSession != null) {
            log.info("close original session-start");
            try {
                oldSession.close();
            } catch (IOException e) {
                log.info("close original session failed");
            }
        }
        //新的会话放入
        WebSocketCommon.CLIENT_SESSION.put(WebSocketCommon.getMapKey(session),session);
    }

    
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage message){
        log.info("handle message start");
        try {
            //String mess = (String) message.getPayload();  //获取客户端发送的消息
            //这边可能需要处理更新map里session机制,防止map里面保存的失效,待定,等后面实际运行观察
            if(session.isOpen()){
                //心跳响应包
                session.sendMessage(new PongMessage());
            }
        } catch (Exception e) {
            log.error("e", e);
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.info("handle message start");
        if (session.isOpen()) {
            session.close();
        }
        log.error("connect error", exception);
        Object userid = session.getAttributes().get(WebSocketConstants.TOKEN).toString();
        if(userid==null){
            return;
        }
        WebSocketCommon.CLIENT_SESSION.remove(WebSocketCommon.getMapKey(session));
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus){
        log.error("在线人数: {}" + WebSocketCommon.CLIENT_SESSION.size());
        log.error("connection closed: " + closeStatus);
        WebSocketCommon.CLIENT_SESSION.remove(WebSocketCommon.getMapKey(session));
        log.error("在线人数: {}" + WebSocketCommon.CLIENT_SESSION.size());
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}

3.WebSocketInterceptor

package com.ruoyi.interceptor;

import com.ruoyi.common.core.constant.WebSocketConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import java.util.Map;

@Component
public class WebSocketInterceptor implements HandshakeInterceptor {

    private static final Logger log = LoggerFactory.getLogger(WebSocketInterceptor.class);

    //在握手之前执行该方法, 继续握手返回true, 中断握手返回false. 通过attributes参数设置WebSocketSession的属性
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes){
        if (request instanceof ServletServerHttpRequest) {
            String uri = request.getURI().getPath();
            String token = uri.substring(uri.lastIndexOf("/")+1);
            attributes.put(WebSocketConstants.TOKEN,token);
            log.info("current token is:"+token);
        }
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
        log.info("coming webSocketInterceptor afterHandshake method...");
    }

}
二.nacos中关键配置

在ruoyi-gateway-dev.yml 配置文件中添加如下,我是在ruoyi-collection这个模块中使用websocket的,所以配置路由到这个服务

        # websocket模块
        - id: ruoyi-websocket
          uri: lb:ws://ruoyi-collection
          predicates:
            - Path=/wsv2/api-docs
      - /csrf
      - /collection/sendBoxStatus
      - /ws
    public static ConcurrentHashMap CLIENT_SESSION = new ConcurrentHashMap();

    public static String getMapKey(WebSocketSession session){
        Object userId = session.getAttributes().get(WebSocketConstants.TOKEN);
        if(userId==null){
            return null;
        }
        String useridStr = userId.toString();
        return useridStr;
    }
}

最后非常感谢这篇文章的作者,参照这篇文章实现了功能,另外有什么问题欢迎留言,一起探讨。

SpringCloud Gateway 集成 WebSocket服务_哦哈哟小朋友的博客-CSDN博客_gateway整合websocket

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/999000.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号