Jetty WebSocketClientSelectorManager - 连接失败 java.io.IOException:无法初始化 SSL

Jetty WebSocketClientSelectorManager - Connection Failed java.io.IOException: Cannot init SSL

我预先为所有代码道歉,但我很困惑为什么同样的代码以前似乎有效但现在却无效。

我有一个简单的 Jetty WebSockets 客户端,但在标题中出现错误。有趣的是,我有一个 HTML 文件和 javascript 来运行同一个 SSL 服务器,它工作正常。

与此错误相关的 Internet 搜索结果不多。

根据码头源代码,没有SSL上下文:

        if ("wss".equalsIgnoreCase(scheme))
        {
            // Encrypted "wss://"
            SslContextFactory sslContextFactory = getSslContextFactory();
            if (sslContextFactory != null)
            {
                SSLEngine engine = newSSLEngine(sslContextFactory,channel);
                SslConnection sslConnection = new SslConnection(bufferPool,getExecutor(),endPoint,engine);
                sslConnection.setRenegotiationAllowed(sslContextFactory.isRenegotiationAllowed());
                EndPoint sslEndPoint = sslConnection.getDecryptedEndPoint();

                Connection connection = newUpgradeConnection(channel,sslEndPoint,connectPromise);
                sslEndPoint.setIdleTimeout(connectPromise.getClient().getMaxIdleTimeout());
                sslEndPoint.setConnection(connection);
                return sslConnection;
            }
            else
            {
                throw new IOException("Cannot init SSL");
            }
        }
        else
        {
            // Standard "ws://"
            endPoint.setIdleTimeout(connectPromise.getDriver().getPolicy().getIdleTimeout());
            return newUpgradeConnection(channel,endPoint,connectPromise);
        }

这是执行的回溯 运行:

20:32:15.560 [main] INFO  c.d.e.w.EspClientMain - client connected, waiting for close
20:32:15.626 [WebSocketClient@841038702-14] DEBUG o.e.j.i.SelectorManager - Queued change org.eclipse.jetty.io.SelectorManager$ManagedSelector$Connect@7703d828
20:32:15.627 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.SelectorManager - Selector loop woken up from select, 0/0 selected
20:32:15.628 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.SelectorManager - Running change org.eclipse.jetty.io.SelectorManager$ManagedSelector$Connect@7703d828
20:32:15.629 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.SelectorManager - Selector loop waiting on select
20:32:15.630 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.SelectorManager - Selector loop woken up from select, 1/1 selected
20:32:15.636 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.w.c.i.WebSocketClientSelectorManager - newEndPoint(java.nio.channels.SocketChannel[connected local=/10.214.156.230:39311 remote=node.dj2.dfdev.biz/10.214.156.230:8443], org.eclipse.jetty.io.SelectorManager$ManagedSelector@36971840 keys=1 selected=1, sun.nio.ch.SelectionKeyImpl@2c21a48f)
20:32:15.648 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.AbstractEndPoint - onOpen SelectChannelEndPoint@2029c7d5{node.dj2.dfdev.biz/10.214.156.230:8443<->39311,Open,in,out,-,-,300000,null}{io=0,kio=0,kro=8}
20:32:15.648 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.i.IdleTimeout - SelectChannelEndPoint@2029c7d5{node.dj2.dfdev.biz/10.214.156.230:8443<->39311,Open,in,out,-,-,300000,null}{io=0,kio=0,kro=8} idle timeout check, elapsed: 6 ms, remaining: 299994 ms
20:32:15.649 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] DEBUG o.e.j.w.c.i.WebSocketClientSelectorManager - newConnection(java.nio.channels.SocketChannel[connected local=/10.214.156.230:39311 remote=node.dj2.dfdev.biz/10.214.156.230:8443],SelectChannelEndPoint@2029c7d5{node.dj2.dfdev.biz/10.214.156.230:8443<->39311,Open,in,out,-,-,300000,null}{io=0,kio=0,kro=8},FutureCallback@7b93372{false,false,null})
20:32:15.654 [WebSocketClient@841038702-13-selector-WebSocketClientSelectorManager@2db493c7/0] INFO  c.d.e.w.EspClientMain$EspClient - unexpected websockets exception: {}
java.io.IOException: Cannot init SSL
    at org.eclipse.jetty.websocket.client.io.WebSocketClientSelectorManager.newConnection(WebSocketClientSelectorManager.java:96) ~[datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.io.SelectorManager$ManagedSelector.createEndPoint(SelectorManager.java:735) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.io.SelectorManager$ManagedSelector.processConnect(SelectorManager.java:676) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.io.SelectorManager$ManagedSelector.processKey(SelectorManager.java:640) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.io.SelectorManager$ManagedSelector.select(SelectorManager.java:607) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.io.SelectorManager$ManagedSelector.run(SelectorManager.java:545) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.util.thread.NonBlockingThread.run(NonBlockingThread.java:52) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:620) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:540) [datafascia-emerge-websocket-esp-client-1.0-SNAPSHOT.jar:na]
    at java.lang.Thread.run(Thread.java:745) [na:1.7.0_71]

我创建连接的来源非常简单,似乎遵循示例:

// Run forever and recover lost server connections
while (true) {
  WebSocketClient client = new WebSocketClient();
  EspClient socket = new EspClient();
  try {
    logger.info("starting client");
    client.start();
    logger.info("client started");
    URI espServerURI = new URI(espURI);
    logger.info("requesting WebSockets upgrade");
    ClientUpgradeRequest request = new ClientUpgradeRequest();
    logger.info("WebSockets upgrade complete, connecting");
    client.connect(socket, espServerURI, request);
    logger.info("client connected, waiting for close");

    try {
      socket.awaitClose();
    } catch (InterruptedException e) {
      logger.error("sleep interrupted ...", e);
    }
  } catch (Throwable t) {
    logger.error("could not connect to {}: {}", espURI, t);
    try {
      Thread.sleep((long)(10 * DateTimeConstants.MILLIS_PER_SECOND));
    } catch (Exception e) {
      logger.error("sleep interrupted ...", e);
    }
  } finally {
    try {
      logger.error("unexpected ESP Server termination.  Retrying connection: {}", espURI);
      client.stop();
      Thread.sleep((long)(10 * DateTimeConstants.MILLIS_PER_SECOND));
    } catch (Exception e) {
      logger.error("exception stopping the ESP client: {}", e);
    }
  }
}

客户class是普通人:

      /**
       * The Emerge ESP WebSockets Client
       */
      public static class EspClient extends WebSocketAdapter {
    private Logger logger = LoggerFactory.getLogger(EspClient.class);
    private final String pingMessage = "I am still here";
    private final ByteBuffer pingBuffer = ByteBuffer.wrap(pingMessage.getBytes());

    private final CountDownLatch closeLatch;

    // Setup the JMS queues
    private static AbstractApplicationContext context =
        new ClassPathXmlApplicationContext("applicationContext.xml");
    private static JmsConnector jmsEspConnection =
        (JmsConnector) context.getBean("JmsEspMessageBean");

    /**
     * Setup the synchronization
     */
    public EspClient() {
      this.closeLatch = new CountDownLatch(1);
    }

    /**
     * Synchronizes on the countdown latch.
     */
    public void awaitClose() throws InterruptedException {
      this.closeLatch.await();
    }

    @Override
    public void onWebSocketClose(int statusCode, String reason) {
      logger.error("ESP Server session closed: {}, {}", statusCode, reason);
      espSession = null;
      this.closeLatch.countDown();
    }

    @Override
    public void onWebSocketConnect(Session session) {
      logger.info("Connected: {}", session);
      espSession = session;
      readAndSendMessage();
    }

    @Override
    public void onWebSocketError(Throwable cause) {
      logger.info("unexpected websockets exception: {}", cause);
      espSession = null;
    }

    @Override
    public void onWebSocketBinary(byte[] payload, int offset, int len) {
      logger.info("unexpected binary message received");
    }

    @Override
    public void onWebSocketText(String message) {
      if (message != null) {
        logger.info("received ESP Server response: {}", message);
      }
    }
    /**
     * Reads a message from the ESP queue and sends it to the ESP server.
     */
    private void readAndSendMessage() {
      while (espSession != null) {
        String message = jmsEspConnection.receiveTextMessage((long)(4 * DateTimeConstants.MILLIS_PER_MINUTE));
        if (message != null) {
          logger.info("read message: {}", message);
          sendMessage(message);
        } else {
          logger.info("no message available, sending keepalive message");
          try {
            espSession.getRemote().sendPing(pingBuffer);
          } catch (IOException e) {
            logger.error("error sending keepalive message to ESP Server: {}", e);
          }
        }
      }
      logger.error("ESP Server connection lost");
    }

    /**
     * Sends a message to the ESP server.
     */
    private void sendMessage(String message) {
      if (espSession != null) {
        try {
          espSession.getRemote().sendString(message);
        } catch (Exception e) {
          logger.error("error sending sensor message to ESP Server: {}", e);
          espSession = null;
        }
      }
    }
  }

您需要在构造函数中提供 SslContextFactory

又名:

SslContextFactory ssl = new SslContextFactory();
// Configure ssl for your client here, such as
// what ciphers and protocols are available,
// what client certificates to use,
// what CA's you want to validate against,
// what your blacklist behavior is,
// your truststore location and access,
// your keystore location and access,
// caching, CRL, OCSP, renegotiation, etc ...

WebSocketClient client = new WebSocketClient(ssl);