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());
        }
    }
    
  • 相关阅读:
    笔记:一篇关于容器和虚拟机的对比
    语义化版本说明脑图
    KiCad EDA 5.1.4 发布了
    KiCad 5.1.4 无法覆铜?
    mac 常用的终端命令
    PC 商城扫描二维码登录
    Git的撤销与回滚
    springboot 集成elasticsearch5.4.3
    redis 缓存类型为map
    基于Elasticsearch 5.4.3的商品搜索系统
  • 原文地址:https://www.cnblogs.com/seliote/p/15001612.html
Copyright © 2011-2022 走看看