我正在使用Jetty9.4.18库在java应用程序中编写一个WebSocket客户机。
我是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下载了另一个websocket实现,它在ws和wss上都工作得很好,没有为SSL设置任何特定的东西。然而,对于这个项目,我必须使用Jetty。
我使用的代码与https://www.eclipse.org/jetty/documentation/9.4.x/jetty-websocket-client-api.html的Jetty文档中的示例完全相同
我所做的唯一更改是向SimpleEchoSocket添加了一个onError方法,它转储了整个异常堆栈。
我是不是遗漏了什么?
提前感谢!
发布于 2019-05-10 03:34:29
不幸的是,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);
}
}
https://stackoverflow.com/questions/56063746
复制相似问题