You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

javax.websocket客户端WSS连接异常求助(Eclipse IDE+Jetty 9)

解决Jetty 9下javax.websocket客户端wss协议连接问题

我之前处理过Jetty 9结合javax.websocket客户端使用wss协议的场景,你的问题核心在于标准的WebSocket容器不会自动加载自定义SSL配置,得手动关联Jetty的SslContextFactory到客户端实例里。下面一步步给你解决:

核心思路

Jetty的javax.websocket实现依赖WebSocketClient来处理底层连接,我们需要先配置好支持SSL的SslContextFactory.Client,再把它绑定到WebSocketClient,最后通过Jetty的ClientContainer来创建JSR356标准的会话。

完整代码示例

import java.io.FileInputStream;
import java.net.URI;
import java.security.KeyStore;
import javax.websocket.ClientEndpoint;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.jsr356.ClientContainer;

@ClientEndpoint
public class WssWebSocketClient {

    @OnOpen
    public void onSessionOpen(Session session) {
        System.out.println("成功建立wss连接:" + session.getRequestURI());
    }

    @OnMessage
    public void onMessageReceived(String message) {
        System.out.println("收到服务器消息:" + message);
    }

    public static void main(String[] args) throws Exception {
        // 1. 配置SSL上下文工厂(客户端专用)
        SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();

        // 场景1:服务器使用自签名证书,加载自定义密钥库
        KeyStore trustStore = KeyStore.getInstance("JKS");
        try (FileInputStream fis = new FileInputStream("你的密钥库路径/truststore.jks")) {
            trustStore.load(fis, "密钥库密码".toCharArray());
        }
        sslContextFactory.setTrustStore(trustStore);
        sslContextFactory.setTrustStorePassword("密钥库密码");

        // 场景2:测试环境临时信任所有证书(生产环境绝对禁用!)
        // sslContextFactory.setTrustAll(true);

        // 2. 初始化Jetty WebSocket客户端
        WebSocketClient jettyClient = new WebSocketClient(sslContextFactory);
        jettyClient.start();

        // 3. 获取JSR356标准的客户端容器
        ClientContainer clientContainer = ClientContainer.getContainer(jettyClient);

        // 4. 连接wss地址
        URI wssUri = new URI("wss://你的服务器地址:端口/websocket路径");
        Session session = clientContainer.connectToServer(WssWebSocketClient.class, wssUri);

        // 发送测试消息
        session.getBasicRemote().sendText("Hello WSS Client!");

        // 保持连接(按需调整,实际业务中可通过阻塞或监听事件处理)
        Thread.sleep(10000);

        // 关闭资源
        session.close();
        jettyClient.stop();
    }
}

关键细节说明

  • 为什么不用标准ContainerProvider?:标准的ContainerProvider.getWebSocketContainer()会创建默认容器,但不会自动应用我们的SSL配置,手动绑定Jetty的WebSocketClient才能确保SSL上下文生效。
  • SSL配置的两种场景:
    • 生产环境:必须加载信任库,只信任合法的服务器证书,避免安全风险。
    • 测试环境:可以临时开启setTrustAll(true),但上线前一定要删掉这个配置。
  • 依赖检查:确保你的项目引入了Jetty 9的相关依赖,比如jetty-websocket-client、jetty-util、jetty-websocket-jsr356,版本要统一。

常见问题排查

如果还是连接失败,可以试试这些方法:

  • 开启Jetty的调试日志,查看SSL握手过程:
    import org.eclipse.jetty.util.log.Log;
    import org.eclipse.jetty.util.log.StdErrLog;
    
    public static void main(String[] args) throws Exception {
        // 开启调试日志
        StdErrLog debugLog = new StdErrLog();
        debugLog.setLevel(StdErrLog.LEVEL_DEBUG);
        Log.setLog(debugLog);
    
        // 后续代码不变...
    }
    
    日志会告诉你具体的错误,比如证书不被信任、协议版本不兼容(Jetty 9默认支持TLS 1.2+,如果服务器用旧协议,可通过sslContextFactory.setIncludeProtocols("TLSv1.2")指定)。
  • 检查服务器端的SSL端口是否开放,防火墙是否允许客户端访问。
  • 确认wss地址的格式正确,比如wss://domain:port/path,不要遗漏端口(默认443可以省略)。

内容的提问来源于stack exchange,提问作者Mikhail Stepanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:24:09