码头 websocket 客户端问题

Posted

技术标签:

【中文标题】码头 websocket 客户端问题【英文标题】:Jetty websocket client issue 【发布时间】:2019-11-23 13:03:59 【问题描述】:

使用 Eclipse IDE 尝试为 OpenHab 项目创建 java websocket 客户端,从而使用默认的 Jetty websocket 库。 OpenHab 项目打算连接到需要令牌授权的 websocket 端点,发送请求消息并检索实时/连续测量值。

所以,我有

public static final String SUBSCRIPTION_URL = "wss://api.tibber.com/v1-beta/gql/subscriptions";

另外,我的WS开放代码:

public void open() throws Exception 
    if (isConnected()) 
        logger.warn("Open: connection is already open");
    
    logger.warn("Connecting to: ", SUBSCRIPTION_URL);

    sslContextFactory = new SslContextFactory(true);
    sslContextFactory.setTrustAll(true);

    client = new WebSocketClient(sslContextFactory);
    client.setMaxIdleTimeout(360 * 1000);

    TibberWebSocketListener socket = new TibberWebSocketListener();

    request = new ClientUpgradeRequest();
    String token = new StringBuilder("Bearer ").append(configuration.getToken()).toString();
    request.setHeader("Authorization", token);
    request.setSubProtocols("graphql-subscriptions");

    client.start();
    client.connect(socket, new URI(SUBSCRIPTION_URL), request);


但是,使用此代码,我似乎已连接,但在 1 分钟后出现 IOException: Broken pipe。如果我只是连接而不发送消息/连接发送消息,我会得到相同的错误。

   13:59:15.987 [safeCall-1] WARN  o.o.b.t.i.handler.TibberHandler:346 - Connecting to: wss://api.tibber.com/v1-beta/gql/subscriptions
13:59:16.390 [@1379116703-141] WARN  o.o.b.t.i.handler.TibberHandler:385 - Connected to Server
14:00:16.430 [@1379116703-142] WARN  o.o.b.t.i.handler.TibberHandler:392 - Closing a WebSocket due to Disconnected
14:00:16.434 [@1379116703-139] WARN  o.o.b.t.i.handler.TibberHandler:399 - Error during websocket communication: Broken pipe
java.io.IOException: Broken pipe
    at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.flush(SslConnection.java:928)
    at org.eclipse.jetty.io.WriteFlusher.flush(WriteFlusher.java:422)
    at org.eclipse.jetty.io.WriteFlusher.write(WriteFlusher.java:277)
    at org.eclipse.jetty.io.AbstractEndPoint.write(AbstractEndPoint.java:381)
    at org.eclipse.jetty.websocket.common.io.FrameFlusher.flush(FrameFlusher.java:264)
    at org.eclipse.jetty.websocket.common.io.FrameFlusher.process(FrameFlusher.java:193)
    at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:241)
    at org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:223)
    at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.outgoingFrame(AbstractWebSocketConnection.java:516)
    at org.eclipse.jetty.websocket.client.io.WebSocketClientConnection.outgoingFrame(WebSocketClientConnection.java:72)
    at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.close(AbstractWebSocketConnection.java:184)
    at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:458)
    at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:428)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:426)
    at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:320)
    at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:158)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:367)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:782)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:918)
    at java.lang.Thread.run(Thread.java:748)
14:00:16.435 [@1379116703-139] WARN  o.o.b.t.i.handler.TibberHandler:392 - Closing a WebSocket due to Broken pipe

【问题讨论】:

【参考方案1】:

java.io.IOException: 损坏的管道

这意味着 Java(和 Jetty)以下的操作系统或网络检测到连接已关闭。

“Broken Pipe”实际上相当普遍,尤其是在移动设备或无线网络中。

Java 或 Jetty 也无能为力,它发生在它的控制之外。

【讨论】:

以上是关于码头 websocket 客户端问题的主要内容,如果未能解决你的问题,请参考以下文章

websock第一次连不上window

码头 WebSocket 服务器

码头 websocket 中的 ProtocolException 是啥意思?

Android websock 应用

初识Websocket

使用 websocket 时的奇怪行为