Проблема с клиентом Jetty 9 WebSocket при использовании безопасного соединения

Я пишу клиент WebSocket в java-приложении, используя библиотеки Jetty 9.4.18.

Я новичок в WebSockets, поэтому я начал тестирование, используя два примера классов из документации Jetty, подключившись к echo.websocket.org

Тест проходит нормально, когда я подключаюсь без SSL, но в случае сбоя при подключении к wss://echo.websocket.org

Я всегда получаю одно и то же исключение:

java.io.EOFException: HttpConnectionOverHTTP@50371e9d::DecryptedEndPoint@6dc65fc2{echo.websocket.org/174.129.224.73:443<->/192.168.1.34:60521,OPEN,fill=-,flush=C,to=226/0}
    at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.earlyEOF(HttpReceiverOverHTTP.java:338)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1551)
    at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.shutdown(HttpReceiverOverHTTP.java:209)
    at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.process(HttpReceiverOverHTTP.java:147)
    at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:73)
    at org.eclipse.jetty.client.http.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:133)
    at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:155)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:411)
    at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:305)
    at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:159)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
    at java.lang.Thread.run(Thread.java:748)

Похоже, сервер закрывается, не отвечая на запрос рукопожатия.

Я знаю о SslContextFactory, но, насколько я понимаю, его следует использовать только в том случае, если вам нужен собственный TrustStore или KeyStore или для других особых случаев.

Также обратите внимание, что после неудачной попытки я загрузил другую реализацию веб-сокета из https://github.com/TooTallNate/Java-WebSocket, и она отлично работает как с ws, так и с wss, не устанавливая ничего конкретного для SSL. Однако для этого проекта я обязан использовать Jetty.

Код, который я использую, точно соответствует образцу из документации Jetty по адресу https://www.eclipse.org/jetty/documentation/9.4.x/jetty-websocket-client-api.html.

единственное изменение, которое я сделал, это добавить метод onError в SimpleEchoSocket, который сбрасывает полный стек исключений.

Я что-то пропустил?

Заранее спасибо!

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
1 689
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

К сожалению, на данный момент у websocket.org (и хоста/прокси Kaazing) есть куча проблем с TLS, поэтому использование их общедоступных серверов сейчас не является разумным выбором.

Вот другая демонстрация, также использующая TLS и WebSocket, против сервера stackexchange с правильной и разумной реализацией TLS/SSL.

Это было написано против Jetty 9.4.18.v20190429

package org.eclipse.jetty.demo;

import java.net.URI;
import java.util.concurrent.Future;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.client.WebSocketClient;

@WebSocket
public class SecureClientSocket
{
    private static final Logger LOG = Log.getLogger(SecureClientSocket.class);

    public static void main(String[] args)
    {
        String url = "wss://qa.sockets.stackexchange.com/";

        SslContextFactory ssl = new SslContextFactory.Client();
        ssl.setEndpointIdentificationAlgorithm("HTTPS");
        HttpClient http = new HttpClient(ssl);
        WebSocketClient client = new WebSocketClient(http);
        try
        {
            http.start();
            client.start();
            SecureClientSocket socket = new SecureClientSocket();
            Future<Session> fut = client.connect(socket, URI.create(url));
            Session session = fut.get();
            session.getRemote().sendString("Hello");
            session.getRemote().sendString("155-questions-active");
        }
        catch (Throwable t)
        {
            LOG.warn(t);
        }
        finally
        {
            stop(http);
            stop(client);
        }
    }

    private static void stop(LifeCycle lifeCycle)
    {
        try
        {
            lifeCycle.stop();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    @OnWebSocketConnect
    public void onConnect(Session sess)
    {
        LOG.info("onConnect({})", sess);
    }

    @OnWebSocketClose
    public void onClose(int statusCode, String reason)
    {
        LOG.info("onClose({}, {})", statusCode, reason);
    }

    @OnWebSocketError
    public void onError(Throwable cause)
    {
        LOG.warn(cause);
    }

    @OnWebSocketMessage
    public void onMessage(String msg)
    {
        LOG.info("onMessage() - {}", msg);
    }
}

Ваш вопрос заставил меня добавить обновленный пример использования wss://echo.websocket.org/ (причина, по которой это не удалось, связана с тем, что echo.websocket.org использует только ужасно слабые наборы шифров, которые устарели много лет назад. наборы шифров, которые пристань не будет использовать по умолчанию) - см. github.com/eclipse/jetty.project/pull/3643

Joakim Erdfelt 10.05.2019 16:12

Скорректированный пример для безопасных веб-сокетов (для обхода недостатков TLS/SSL в echo.websocket.org теперь проверяются) — github.com/eclipse/jetty.project/blob/jetty-9.4.x/…

Joakim Erdfelt 14.05.2019 16:21

Другие вопросы по теме