zoukankan      html  css  js  c++  java
  • OkHTTP 重写 WebSocket 请求头

    问题背景

    对方 WebSocket 有问题,握手时返回的响应头含有两个 Connection,一个为 upgrade 另一个为 close,导致协议升级失败,具体报错为 WsListener 587802424 on failure, exception java.net.ProtocolException, exception message Expected 'Connection' header value 'Upgrade' but was 'close', code 101, response Switching Protocols

    解决方式

    重写响应头,移除 close 值,解决方案是 Okhttp 新增拦截器,移除错误的请求头

    package cn.crservice.sbktransfer.lmd;
    
    import cn.crservice.sbktransfer.config.YmlConfig;
    import lombok.extern.slf4j.Slf4j;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.Response;
    import okhttp3.WebSocket;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    import java.time.Duration;
    import java.time.temporal.ChronoUnit;
    import java.util.List;
    
    @Slf4j
    @Component
    public class WsInit {
    
        private final YmlConfig.Websocket websocketConfig;
        private WebSocket webSocket;
    
        @Autowired
        public WsInit(YmlConfig ymlConfig) {
            this.websocketConfig = ymlConfig.getWebsocket();
        }
    
        /**
         * 初始化当前 WebSocket 连接
         */
        @PostConstruct
        public void init() {
            log.info("Initialization websocket");
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    // 对方 WebSocket 存在双 Connection,且最后一个为 close,导致握手失败,定义拦截器进行移除
                    .addInterceptor(chain -> {
                        Request request = chain.request();
                        Response response = chain.proceed(request);
                        List<String> headers = response.headers("Connection");
                        // 重写 Connection 响应头
                        if (headers.size() == 2 && headers.contains("upgrade") && headers.contains("close")) {
                            return response.newBuilder().header("Connection", "upgrade").build();
                        }
                        return response;
                    })
                    .pingInterval(Duration.of(10, ChronoUnit.SECONDS))
                    .build();
            Request request = new Request.Builder().url(websocketConfig.getUrl().getLmd()).build();
            webSocket = okHttpClient.newWebSocket(request, new WsListener());
        }
    }
    
  • 相关阅读:
    Requests库入门——应用实例-网络图片的爬取与保存(好看的小姐姐≧▽≦)
    Python Requests库简单入门
    Python BeautifulSoup库基础及一般元素提取方法
    Coloring a Tree(耐心翻译+思维)
    Python jieba库的使用说明
    竖式除法模拟
    Pythagorean Triples毕达哥斯拉三角(数学思维+构造)
    C++ STL中的Binary search(二分查找)
    Polycarp and Letters(set首战!)
    Java多线程干货系列—(一)Java多线程基础
  • 原文地址:https://www.cnblogs.com/seliote/p/15001612.html
Copyright © 2011-2022 走看看