Клиент WebSocket закрывается при подключении - PullRequest
0 голосов
/ 10 октября 2019

Я пытаюсь создать автономный клиент WebSocket на Java, который подключается к серверу WebSocket в C #. Я использую самоподписанный сертификат, созданный для сервера WebSocket. Я могу подключиться к серверу WebSocket в моем браузере Chrome с помощью WSS без каких-либо проблем. При попытке использовать библиотеку TooTallNate / Java-WebSocket она не работает. Метод OnClose вызывается сразу при подключении.

У меня есть самоподписанный сертификат в сгенерированном файле * .pfx, который я использую для сервера C #, и он импортируется в мое хранилище доверенных корней. Я создал * .jks из этого файла, используя keytool (я думаю, что сделал это правильно). Я использую keystore.jks, который был сгенерирован keytool в моем коде.

Вот мой основной метод:

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

Есть ли какой-нибудь способ, которым я мог бы получить больше информации о рукопожатии или какова реальная проблема? Трассировка стека исключений, похоже, совсем не помогает.

1 Ответ

0 голосов
/ 11 октября 2019

Моя проблема заключалась в том, что мой локальный брандмауэр вызывал проблемы. Я также обнаружил, что могу установить сертификат в доверенное корневое хранилище Java.

Обратите внимание, что каждая версия Java (JDK и JRE) имеет свой собственный файл "cacerts". Обязательно установите правильную версию для вашей среды разработки или среды выполнения. Я ударился головой о стену, потому что она не работала в IntelliJ, пока я не осознал это.

  1. Установить сертификат в доверенное корневое хранилище JVM
  2. Проверьте, правильно ли он установлен
  3. Удалите часть вашего кода из хранилища ключей

Вот изменение моего кода после установки сертификата в нужное место.

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 );
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...