Spring WebSockets 的 SockJsClient 中的编程代理支持

问题描述 投票:0回答:0

我正在开发一个微型 Java 15 应用程序,它使用 STOMP over WebSockets 连接到基于 Spring Boot 的基础设施。基本上这很容易,但不幸的是,公司代理设置非常令人不安。由于公司安全策略可能需要针对不同应用程序的不同代理,因此应该可以通过编程方式进行配置。

如前所述,应用程序是用 Java 15 编写的,我提到 spring-websockets 和 spring-messaging 的 pom.xml 看起来像这样:

<!-- ... -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>5.2.11.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-messaging</artifactId>
    <version>5.2.11.RELEASE</version>
</dependency>
<!-- ... -->

对于我使用标准 Java HttpClients 的其他应用程序,它真的很简单。在这种情况下,像这样配置 HttpClient 就足够了:

HttpClient.newBuilder().proxy( ProxySelector.of( new InetSocketAddress( proxyHostAddr, proxyPort ) ) ).authenticator( proxyAuthenticator ).build();

因为 WebSockets 确实基于 HTTP 协议,我假设在 Spring 宇宙中有一个地方我可以获取底层 HttpClient(当然如果使用的话)并更新其代理设置。

通过以下片段,我初始化了一个非常基本的 STOMP 客户端:

// Set up WebSocket connection transports (different ways to communicate with a WS server)
List<Transport> transports = new ArrayList<>( 2 );
transports.add( new WebSocketTransport( new StandardWebSocketClient() ) );
transports.add( new RestTemplateXhrTransport() );

this.stompClient = new WebSocketStompClient( new SockJsClient( transports ) );

我无法找到在哪里可以拦截或实现接口或类似的东西来仅交换代理设置。

我只有一种方法可以让它运行:在将我的应用程序构建为 .jar 时,我可以通过像这样调用 JAR 来告诉 JVM 使用哪些代理:

java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8081 -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=8081 -jar myJar.jar

因为我不知道每个客户的代理设置,所以这个解决方案是不可接受的,它也会导致这个 JVM 实例中的所有网络内容都是通过代理引导的情况。

提前致谢!

编辑: 由于我调试了几个小时,现在我发现了一些新东西:底层 WebSocket 实现是

org.apache.tomcat.websocket.WsWebSocketContainer
。在此类中,使用
ProxySelector.getDefault()
调用检索系统代理。不幸的是,此类不提供任何方法来覆盖代理的收集方式。在最坏的情况下,我必须复制整个 800 行的类并只替换特定的代码段。但是我觉得这样做很不舒服。也许这里的观众中有人有线索。

java spring stomp spring-websocket sockjs
© www.soinside.com 2019 - 2024. All rights reserved.