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);
我预先为所有代码道歉,但我很困惑为什么同样的代码以前似乎有效但现在却无效。
我有一个简单的 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);