Tyrus websocket客户端@OnMessage永远不会调用 – Storj开源项目

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

  • 客户端发送身份validation令牌(文本)。
  • 服务器发回一个文件(二进制)。
  • 服务器closures连接。

我有问题,因为我的@OnMessage永远不会被调用。 我已经在这里尝试了一个简单的JavaScript客户端在这里相同的URL和相同的令牌: https : //www.websocket.org/echo.html

我得到了一个使用这个响应,这告诉我有什么是错误的Java项目。

在能够下载文件之前,我可以在没有任何问题的情况下上传文件。 然而,这一步不需要@OnMessage被调用(它只是上传文件,然后服务器断开连接的消息),所以我不知道我的@OnMessage是否曾经工作过。

以下是Websocket的相关代码(也可在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(); } } 

以及这个websocket的代码,可在这里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); } 

我也尝试将Tyrus升级到最新版本,并得到相同的结果。 有任何想法吗?

这个代码的输出是:

  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 

在发送消息之后,它会在@OnClose的“NORMAL_CLOSURE”消息之前挂起一段时间。

更新:一个非常简单的方法来运行这个来重现这个问题

我已经添加了一个testing用户名和密码到git仓库,所以可用的代码在这里: https : //github.com/NutterzUK/storj-java-bridge-client

运行它,你只需要运行storj.io.client.main.MainTest

快速浏览它的function。 它会首先发送一些HTTP请求来获取令牌。 它将使用该令牌通过websocket连接到某人的机器,并将该令牌作为文本发送。 作为响应,它应该以字节接收文件。

在连接之前,它会打印出令牌和要连接的地址。 在closures之前它会挂起一点,并且不会调用onMessage方法。 为了testing,如果你在那里放置一个System.exit(在DefaultStorjClient.java中取消注释行152),它将不会连接,所以你可以在另一个客户端使用该标记。 我已经使用https://www.websocket.org/echo.html进行了testing(请确保您的浏览器将允许不安全的url,因为它不是“wss”,要在Chrome中执行此操作,您需要点击顶部的屏蔽对,我可以看到服务器确实响应: 显示正在接收的blob的图像

这表明一个blob确实是响应这个文本消息而发送的,但是Tyrus中的@OnMessage永远不会被触发。

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

我发现计时后,它总是断开我30秒后。 通常情况下,回复比30多分钟更快​​,所以我不确定为什么会挂起然后断开连接。 我尝试在Tyrus中设置超时,但是仍然在30s的时候断开连接。 最后,我尝试了一下TallNate,看是否可以在那里设置超时时间,而刚刚开始工作。

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