Tyrus websocket客户端@OnMessage从未调用过--Storj开源项目 [英] Tyrus websocket client @OnMessage never called - Storj Open source project

查看:989
本文介绍了Tyrus websocket客户端@OnMessage从未调用过--Storj开源项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个开源项目Storj。我正在编写一个连接到Node.js websocket后端的Java客户端。客户使用Tyrus。通讯应如下:




  • 连接

  • 客户端发送身份验证令牌(文本)。

  • 服务器发回文件(二进制)。

  • 服务器关闭连接。



我遇到问题,因为我的@OnMessage永远不会被调用。我尝试使用一个简单的javascript客户端在线访问相同的URL并使用相同的标记:



这表明确实发送了一个blob以响应短信,但Tyrus中的@OnMessage永远不会被解雇。

解决方案

最后我切换到TallNate,这个问题不存在。



我在计时之后发现它总是在30秒后断开我。通常响应比30秒更快,所以我不知道为什么它会挂起然后断开连接。我尝试在Tyrus中设置超时但仍然断开连接日最后我尝试了TallNate,看看我是否可以在那里设置超时......开箱即用它只是工作。



https://github.com/TooTallNate/Java-WebSocket/wiki/Drafts


I am working on an open source project, Storj. I am writing a Java client which connects to a Node.js websocket backend. The client uses Tyrus. The communication should go as follows:

  • Connect
  • Client sends auth token (text).
  • Server sends a file back (binary).
  • Server closes connection.

I am having problems as my @OnMessage never gets called. I have tried with a simple javascript client online here to the same URL and with the same token: https://www.websocket.org/echo.html

I do get a response using this, which tells me something is wrong with the Java project.

Before being able to download the file, at an earlier stage, I am able to upload the file without any problems. However, that step does not require an @OnMessage to be called (It just uploads the file and then the server disconnects with a message), so I am not sure if my @OnMessage is ever working.

Here is the relevant code for the Websocket (Also available on Github): https://github.com/NutterzUK/storj-java-bridge-client/blob/master/storj-client/src/main/java/storj/io/client/websockets/WebsocketFileRetriever.java

package storj.io.client.websockets;

import com.google.gson.Gson;
import storj.io.restclient.model.FilePointer;

import javax.websocket.*;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;

import java.util.concurrent.CountDownLatch;
import java.util.logging.Logger;

/**
 * Created by steve on 12/07/2016.
 */
@ClientEndpoint
public class WebsocketFileRetriever {

    private Logger logger = Logger.getLogger(this.getClass().getName());
    private Gson gson = new Gson();
    private FilePointer filePointer;
    private File outputFile;
    private AuthorizationModel authModel;
    private CountDownLatch latch;

    public WebsocketFileRetriever(FilePointer filePointer, File outputFile, CountDownLatch latch){
        this.filePointer = filePointer;
        this.latch = latch;
        this.outputFile = outputFile;
        authModel = new AuthorizationModel();
        authModel.setToken(filePointer.getToken());
        authModel.setOperation(filePointer.getOperation());
        authModel.setHash(filePointer.getHash());
    }

    @OnMessage
    public void onMessage(String s){
        logger.info("Received ... " + s);
    }

    @OnMessage
    public void onMessage(ByteBuffer message, Session session) {
        logger.info("Received ...." + message);
    }

    @OnOpen
    public void onOpen(Session session, EndpointConfig endpointConfig) {
        logger.info("Opened");
        try {
            session.getBasicRemote().sendText(gson.toJson(authModel), true);
        } catch (IOException e) {
            e.printStackTrace();
        }

        logger.info("sent: " + gson.toJson(authModel));
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        logger.info("Closed Websocket: " + closeReason.getCloseCode() + " " + closeReason.getReasonPhrase());
        //latch.countDown();
    }

    @OnError
    public void onError(Session session, Throwable t) {
        t.printStackTrace();
    }
}

And the code which kicks off this websocket, available here https://github.com/NutterzUK/storj-java-bridge-client/blob/master/storj-client/src/main/java/storj/io/client/DefaultStorjClient.java :

        CountDownLatch latch;
        latch = new CountDownLatch(1);
        ClientManager wsClient = ClientManager.createClient();
        try {
            wsClient.setDefaultMaxBinaryMessageBufferSize(Integer.MAX_VALUE);
            wsClient.setDefaultMaxTextMessageBufferSize(Integer.MAX_VALUE);
            logger.info("CONNECTING TO: " + "ws://" + pointer.getFarmer().getAddress() + ":" + pointer.getFarmer().getPort());
            final ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build();

            wsClient.connectToServer(new WebsocketFileRetriever(pointer, encryptedOutputFile, latch), cec, new URI("ws://" + pointer.getFarmer().getAddress() + ":" + pointer.getFarmer().getPort()));
            latch.await();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

I have also tried upgrading Tyrus to the latest version, and I get the same result. Any ideas?

The output of this code is:

    Aug 25, 2016 8:55:31 PM storj.io.client.DefaultStorjClient downloadFile
INFO: CONNECTING TO: ws://164.storj.eu:8607
Aug 25, 2016 8:55:35 PM storj.io.client.websockets.WebsocketFileRetriever onOpen
INFO: Opened
Aug 25, 2016 8:55:35 PM storj.io.client.websockets.WebsocketFileRetriever onOpen
INFO: sent: {"token":"06c36d4bac4f07ee1751068b5b2230f22e884b38","hash":"837b79bec927a1d8fa7fedd2ea0bb276e0d86e0f","operation":"PULL"}
Aug 25, 2016 8:56:11 PM storj.io.client.websockets.WebsocketFileRetriever onClose
INFO: Closed Websocket: NORMAL_CLOSURE Closing

After sending the message, it hangs for a while before the "NORMAL_CLOSURE" message from the @OnClose.

Update: A really easy way to run this to reproduce the issue

I've added a test username and password to the git repository, so the code available is here: https://github.com/NutterzUK/storj-java-bridge-client

To run it, you just need to run storj.io.client.main.MainTest

A quick run through of what it does. It'll first send some HTTP requests to get a token. It'll use that token to connect to someone's machine via a websocket, and it'll send that token as text. In response, it should receive a file as bytes.

Before it connects, it prints out the token and the address it is about to connect to. It will hang for a bit before being closed and no onMessage method is ever called. For testing, if you put a System.exit in there (Uncomment Line 152 in DefaultStorjClient.java), it'll not connect so you can use that token in another client. I have tested using https://www.websocket.org/echo.html (Make sure that your browser will allow unsafe URLs as it's not "wss", to do this in Chrome you'll need to click the shield in the top right. I can see the server does respond:

This shows that a blob is indeed sent in response to the text message, but the @OnMessage in Tyrus never gets fired.

解决方案

In the end I switched to TallNate, and this problem doesn't exist.

I found after timing it that it always disconnected me after 30 seconds. Usually responses are quicker than in 30s, so I am not sure why it was hanging then disconnecting. I tried setting the timeout in Tyrus but still it disconnected on the 30s mark. In the end I tried TallNate to see if I could set the timeout there... and out of the box it just worked.

https://github.com/TooTallNate/Java-WebSocket/wiki/Drafts

这篇关于Tyrus websocket客户端@OnMessage从未调用过--Storj开源项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆