Tyrus websocket 客户端@OnMessage 从未被调用 - Storj 开源项目
Tyrus websocket client @OnMessage never called - Storj Open source project
我正在开发一个开源项目 Storj。我正在编写一个连接到 Node.js websocket 后端的 Java 客户端。客户使用 Tyrus。沟通应该如下:
- 连接
- 客户端发送身份验证令牌(文本)。
- 服务器发回文件(二进制)。
- 服务器关闭连接。
我遇到了问题,因为我的@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" 消息之前挂起一段时间。
更新:运行重现问题的真正简单方法
我已将测试用户名和密码添加到 git 存储库,因此可用代码位于:https://github.com/NutterzUK/storj-java-bridge-client
要运行它,你只需要运行storj.io.client.main.MainTest
快速 运行 了解它的功能。它会首先发送一些 HTTP 请求来获取令牌。它将使用该令牌通过 websocket 连接到某人的机器,并将该令牌作为文本发送。作为响应,它应该接收一个字节文件。
在连接之前,它会打印出令牌和即将连接到的地址。它会在关闭之前挂起一点,并且不会调用任何 onMessage 方法。为了进行测试,如果您将 System.exit 放在那里(取消注释 DefaultStorjClient.java 中的第 152 行),它将无法连接,因此您可以在另一个客户端中使用该令牌。我已经使用 https://www.websocket.org/echo.html 进行了测试(确保您的浏览器允许不安全的 URLs,因为它不是 "wss",要在 Chrome 中执行此操作,您需要点击屏蔽在右上角。我可以看到服务器确实响应:
这表明确实发送了一个 blob 以响应文本消息,但 Tyrus 中的 @OnMessage 从未被触发。
最后换成TallNate,这个问题就不存在了
我在计时后发现它总是在 30 秒后断开连接。通常响应比 30 秒更快,所以我不确定为什么它挂起然后断开连接。我尝试在 Tyrus 中设置超时,但它仍然在 30 秒标记处断开连接。最后,我尝试了 TallNate,看看我是否可以在那里设置超时...开箱即用。
我正在开发一个开源项目 Storj。我正在编写一个连接到 Node.js websocket 后端的 Java 客户端。客户使用 Tyrus。沟通应该如下:
- 连接
- 客户端发送身份验证令牌(文本)。
- 服务器发回文件(二进制)。
- 服务器关闭连接。
我遇到了问题,因为我的@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" 消息之前挂起一段时间。
更新:运行重现问题的真正简单方法
我已将测试用户名和密码添加到 git 存储库,因此可用代码位于:https://github.com/NutterzUK/storj-java-bridge-client
要运行它,你只需要运行storj.io.client.main.MainTest
快速 运行 了解它的功能。它会首先发送一些 HTTP 请求来获取令牌。它将使用该令牌通过 websocket 连接到某人的机器,并将该令牌作为文本发送。作为响应,它应该接收一个字节文件。
在连接之前,它会打印出令牌和即将连接到的地址。它会在关闭之前挂起一点,并且不会调用任何 onMessage 方法。为了进行测试,如果您将 System.exit 放在那里(取消注释 DefaultStorjClient.java 中的第 152 行),它将无法连接,因此您可以在另一个客户端中使用该令牌。我已经使用 https://www.websocket.org/echo.html 进行了测试(确保您的浏览器允许不安全的 URLs,因为它不是 "wss",要在 Chrome 中执行此操作,您需要点击屏蔽在右上角。我可以看到服务器确实响应:
这表明确实发送了一个 blob 以响应文本消息,但 Tyrus 中的 @OnMessage 从未被触发。
最后换成TallNate,这个问题就不存在了
我在计时后发现它总是在 30 秒后断开连接。通常响应比 30 秒更快,所以我不确定为什么它挂起然后断开连接。我尝试在 Tyrus 中设置超时,但它仍然在 30 秒标记处断开连接。最后,我尝试了 TallNate,看看我是否可以在那里设置超时...开箱即用。