java - WebSocket 客户端关闭连接

标签 java ssl websocket client

我正在尝试用 Java 构建一个独立的 WebSocket 客户端,该客户端连接到 C# 中的 WebSocket 服务器。我正在使用为 WebSocket 服务器生成的自签名证书。我可以使用 WSS 连接到我的 Chrome 浏览器中的 WebSocket 服务器,没有任何问题。尝试使用 TooTallNate/Java-WebSocket 时图书馆,它不起作用。连接时立即调用 OnClose 方法。

我在生成的 *.pfx 文件中有一个自签名证书,我将其用于 C# 服务器并导入到我的受信任的根存储区。我使用 keytool 从这个文件创建了一个 *.jks(我想我已经正确地完成了这个)。我在我的代码中使用由 keytool 生成的 keystore.jks。

这是我的主要方法:

public static void main(String[] args) throws Exception {
    ChatClient chatclient = new ChatClient("wss://thomas.localnetwork.com:65120/wsserver?userId=Thomas", "Thomas", "1", "1", "L");
    // load up the key store
    String STORETYPE = "JKS";
    String KEYSTORE = "C:\\Users\\thomas\\Desktop\\keystore.jks";
    String STOREPASSWORD = "test12345";
    String KEYPASSWORD = "test";

    KeyStore ks = KeyStore.getInstance( STORETYPE );
    File kf = new File( KEYSTORE );
    ks.load( new FileInputStream( kf ), STOREPASSWORD.toCharArray() );

    KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" );
    kmf.init( ks, KEYPASSWORD.toCharArray() );
    TrustManagerFactory tmf = TrustManagerFactory.getInstance( "SunX509" );
    tmf.init( ks );

    SSLContext sslContext = null;
    sslContext = SSLContext.getInstance( "TLS" );
    sslContext.init( kmf.getKeyManagers(), tmf.getTrustManagers(), null );
    // sslContext.init( null, null, null ); // will use java's default key and trust store which is sufficient unless you deal with self-signed certificates

    SSLSocketFactory factory = sslContext.getSocketFactory();// (SSLSocketFactory) SSLSocketFactory.getDefault();

    chatclient.setSocketFactory( factory );

    chatclient.connectBlocking();

    BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) );
    while ( true ) {
        String line = reader.readLine();
        if( line.equals( "close" ) ) {
            chatclient.closeBlocking();
        } else if ( line.equals( "open" ) ) {
            chatclient.reconnect();
        } else {
            ucm.send( line );
        }
    }
}

这是我收到的异常:

Closed connection on wss://laptop-thomas.compuflex1.com:65120/wsucm_deviceagent?userId=Thomas
javax.net.ssl.SSLException: java.net.SocketException: Connection reset
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1906)
    at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1870)
    at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1815)
    at sun.security.ssl.AppInputStream.read(AppInputStream.java:116)
    at java.io.InputStream.read(InputStream.java:101)
    at org.java_websocket.client.WebSocketClient.run(WebSocketClient.java:424)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:210)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
    at sun.security.ssl.InputRecord.read(InputRecord.java:503)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:928)
    at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
    ... 3 more

有什么方法可以获得有关握手的更多详细信息或实际问题是什么?异常堆栈跟踪似乎根本没有帮助。

最佳答案

我的问题是我的本地防火墙导致了问题。我还发现我可以将证书安装到 Java 的受信任根存储区。

请注意,每个 Java 版本(JDK 和 JRE)都有自己的“cacerts”文件。请务必安装到适合您的开发或运行时环境的正确版本。我一直在用头撞墙,因为它在 IntelliJ 中不起作用,直到我意识到这一点。

  1. > Install the certificate to the JVM trusted root store
  2. > Check if it's been installed correctly
  3. 删除代码中的 keystore 部分

这是将证书安装到正确位置后对我的代码所做的更改。

public static void main(String[] args) throws Exception {
    ChatClient chatclient = new ChatClient("wss://thomas.localnetwork.com:65120/wsserver?userId=Thomas", "Thomas", "1", "1", "L");

    chatclient.connectBlocking();

    BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) );
    while ( true ) {
        String line = reader.readLine();
        if( line.equals( "close" ) ) {
            chatclient.closeBlocking();
        } else if ( line.equals( "open" ) ) {
            chatclient.reconnect();
        } else {
            chatclient.send( line );
        }
    }
}

关于java - WebSocket 客户端关闭连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58327541/

相关文章:

javascript - Knex Heroku 错误 : self signed certificate

java - 如何声明我的 Java WebSocket 端点来使用和生成 JSON?

java - 如何使用现有的 CSR 文件创建 keystore ?

Javamail : copy message to sent folder

java - SWT 文件对话框 : Selecting directories instead of files

Java JList GUI 格式化

python - 使用 Python 的 Apple 推送通知服务

javascript - 套接字 IO V0.7 : How to send message to more that one specific client

websocket - 在vuejs中按下按钮后如何打开Web套接字?

java - 如何制作数据库复制进度对话框?