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());
        }
    }
    
  • 相关阅读:
    分布式系统笔记
    Paxos算法细节详解(一)
    Java G1学习笔记
    Spring Boot 的 10 个核心模块
    k8s 重点
    毕玄:阿里十年,从分布式到云时代的架构演进之路
    netty原理解析
    JVM调优总结(一):基本概念
    《快学 Go 语言》第 16 课 —— 包管理 GOPATH 和 Vendor
    Oracle 检查表空间使用情况
  • 原文地址:https://www.cnblogs.com/seliote/p/15001612.html
Copyright © 2011-2022 走看看