xiaogaotongxue__ 2023-12-22 10:21 采纳率: 73.3%
浏览 8

SpringBoot作为Websocket的客户端,重新连接失败

这是处理WebSocket消息的类


package com.hy.phoneServer.common;

import com.alibaba.fastjson.JSONObject;
import com.hy.phoneServer.client.MyWebSocketClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.BinaryWebSocketHandler;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

import static com.hy.phoneServer.common.CommonClass.handleStringNull;
import static com.hy.phoneServer.common.TokenValidate.getLYToken;

@Component
public class WebSocketAPI extends BinaryWebSocketHandler {

    //
    private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

    private static Boolean Flag = false;//标记,用来判断对方是否接通电话

//      可以通过ApplicationContext来读取配置文件并创建Bean实例
//    private static ApplicationContext context;
//    @Autowired
//    public void setApplicationContext(ApplicationContext context){
//        WebSocketAPI.context = context;
//    }


    private static MyWebSocketClient webSocketClient;

    @Autowired
    public void setMyWebSocketClient(MyWebSocketClient webSocketClient){
        WebSocketAPI.webSocketClient = webSocketClient;
    }

    private static UrlUtils urlUtils;

    @Autowired
    public void setUrlUtils(UrlUtils urlUtils){
        WebSocketAPI.urlUtils = urlUtils;
    }

    public static String messgag;

    private Logger logger = LoggerFactory.getLogger(Logger.class);


    @Override //该方法会在websocket连接成功后被调用
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //WebSocketSession是websocket连接对应的会话
        logger.info("WebSocket建立连接了");
        Flag = false;
    }

    @Override //该方法是在websocket收到消息的时候自动调用
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
        //message 为收到的消息
        byte[] array = message.getPayload().array();
        String utf8String = new String(array, StandardCharsets.UTF_8); // 将二进制数据转换为UTF-8字符串
        logger.info("WebSocket接受消息:"+utf8String);
     
    
    }

    @Override //该方法是在websocket连接出现异常的时候自动调用的
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        //exception记录了异常信息
        errResult();
        logger.info("WebSocket连接出现异常了");
        //重新连接
//        webSocketClient.connect();
        Flag = false;

    }

    @Override //该方法是在websocket连接关闭后自动调用的
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        //status 为关闭的状态
        CacheManager instance = CacheManager.getInstance();
        logger.info(handleStringNull(instance.get("IsCheck")));
        errResult();
        logger.info(status.toString());
        logger.info("webSocketClient地址"+webSocketClient.toString());
        MyWebSocketClient myWebSocketClient = new MyWebSocketClient();
        myWebSocketClient.connect();
        logger.info("WebSocket连接关闭了");
        //重新连接
//        webSocketClient.connect();这里猜测webSocketClient类是单例,不能从容器去获取这个对象
        Flag = false;
    }

    public String getMessgag() {
        return messgag;
    }

 


}

这是连接webSocket的类:

@Component
public class MyWebSocketClient {
    /**
     * 录音设别地址
     */
    static String phoneUrl;
    @Value("${common.phoneUrl}")
    public void setPhoneUrl(String s){
        phoneUrl = s;
    }

    private Logger logger = LoggerFactory.getLogger(Logger.class);

    private WebSocketSession session;

    public void connect() {
        Map<String, Object> lyToken = getLYToken();
        String lytoken = handleStringNull(lyToken.get("Token"));
        logger.info("WebSocket客户端进行连接,获取token:"+lytoken);
        WebSocketClient client = new StandardWebSocketClient();
        try {
            session = client.doHandshake(new WebSocketAPI(), "url"+lytoken).get();
            boolean open = session.isOpen();
            logger.info("当前连接是否成功2:"+open);
//            Timer t = new Timer();
//            t.scheduleAtFixedRate(new TimerTask() {
//                @Override
//                public void run() {
//                    logger.info("进入定时器,当前连接是否成功:"+open);
//                    if(!open){
//                        logger.info("断线重连");
//                        connect();
//                    }
//                }
//            },1000,5000);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

我在本地运行的时候,如果进入webSocket连接关闭方法, webSocketClient.connect();重新连接成功,
但是我发布到tomcat的时候, webSocketClient.connect();就不生效了

  • 写回答

2条回答 默认 最新

  • 小孟多 2023-12-22 11:00
    关注

    从代码上看,你的WebSocket重新连接逻辑在afterConnectionClosed方法中。在本地运行时,重新连接成功,但在发布到Tomcat后不生效。

    这可能是由于Tomcat的一些配置问题导致的。在某些情况下,Tomcat可能会对长时间空闲的连接进行关闭或者限制。你可以尝试检查Tomcat的连接超时配置和WebSocket相关的配置,确保Tomcat对WebSocket连接没有过于严格的限制。

    另外,你也可以在Tomcat的日志中查看是否有关于WebSocket连接被关闭或无法重新连接的错误信息,这可能会为你提供一些线索。同时,确保你的应用部署在Tomcat时,WebSocket相关的依赖和配置都正确地加载和生效了。

    最后,你也可以考虑使用Spring Boot内嵌的Web服务器(如Tomcat、Jetty)进行部署,看看问题是否依然存在。如果问题在内嵌的Web服务器中不存在,那么可能是Tomcat的配置问题导致的。

    评论

报告相同问题?

问题事件

  • 创建了问题 12月22日

悬赏问题

  • ¥15 Java与Hbase相关问题
  • ¥20 bash代码推送不上去 git fetch origin master #失败了
  • ¥15 LOL外服加入了反作弊系统,现在游戏录像rofl文件离线都无法打开
  • ¥15 在centos7安装conda
  • ¥15 c#调用yolo3 dll文件获取的数据对不上
  • ¥20 WPF 如何实现多语言,label 和cs(live Charts)中是否都能翻译
  • ¥15 STM32F103上电短路问题
  • ¥15 打开软件提示错误:failed to get wglChoosePixelFormatARB
  • ¥15 (标签-python|关键词-char)
  • ¥15 python+selenium,在新增时弹出了一个输入框