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());
        }
    }
    
  • 相关阅读:
    创建你的 /proc 文件
    在 /proc 里实现文件
    使用 /proc 文件系统
    printk函数速率限制
    printk函数打开和关闭消息
    printk 函数消息是如何记录的
    mysql存储程序
    Javascript 笔记与总结(1-1)作用域
    Java实现 LeetCode 142 环形链表 II(二)
    Java实现 LeetCode 142 环形链表 II(二)
  • 原文地址:https://www.cnblogs.com/seliote/p/15001612.html
Copyright © 2011-2022 走看看