9

私はオープン ソース プロジェクト、Storj に取り組んでいます。Node.js websocket バックエンドに接続する Java クライアントを作成しています。クライアントは Tyrus を使用します。通信は次のように行われる必要があります。

  • 接続
  • クライアントは認証トークン (テキスト) を送信します。
  • サーバーはファイルを送り返します (バイナリ)。
  • サーバーは接続を閉じます。

@OnMessage が呼び出されないため、問題が発生しています。ここで、同じURLと同じトークンを使用して、単純なjavascriptクライアントをオンラインで試しました: 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を使用してテストしました (「wss」ではないため、ブラウザーが安全でない URL を許可することを確認してください。Chrome でこれを行うには、上部のシールドをクリックする必要がありますサーバーが応答していることがわかります。 ブロブが受信されていることを示す画像

これは、テキスト メッセージへの応答として blob が実際に送信されることを示していますが、Tyrus の @OnMessage は起動されません。

4

1 に答える 1

2

結局、私は TallNate に切り替えましたが、この問題は存在しません。

タイミングを計った後、30秒後に常に切断されることがわかりました。通常、応答は 30 秒よりも速いため、なぜハングしてから切断されたのかわかりません。Tyrus でタイムアウトを設定しようとしましたが、それでも 30 秒で切断されました。最後に、タイムアウトを設定できるかどうかを確認するために TallNate を試しました...そして、箱から出してすぐに機能しました。

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

于 2016-08-28T12:34:10.243 に答える