web-dev-qa-db-ja.com

WebSocketサーバーからリアルタイムデータを取得することを提案します

私は現在GPSベースのプロジェクトに取り組んでおり、現在ボレーを使用してWebからデータを受信して​​いますが、最近、リアルタイムデータでサービスをアップグレードする予定です。そのため、Web開発者はwebsocketを使用してサーバーをプログラムし、ブラウザーアプリケーションの場合、サーバーからデータを取得するためにstomp.jsプロトコルを使用しています。彼らは私に彼らのサーバーからデータを取得するように要求しました(リアルタイムデータ)はいずれかを使用しますが、WebSocketからリアルタイムデータを取得するための最適な方法がわかりません。 githubから1つの例を見つけました https://github.com/NaikSoftware/StompProtocolAndroid しかし、それは私が学ぶのに十分ではなく、stompを使用するためのドキュメントはインターネット上で十分ではありません。 Androidでより良い実装ができることを願っています。

どんな助けや提案もいただければ幸いです。 Firebaseについてはすでに言及しており、使用を拒否しているため、Firebaseについては言及しないでください。ボレーを使用してWebSocketサーバーからデータを取得するための良い例を1つ挙げてください。

8
Apple Appala

私の答えは、この質問のコメントに基づいています。質問に関する十分な情報がないので、私はあなたの質問のために2つの解決策を書いています

解決策1-Stomp実装を使用しない-シンプルなWebSocket

これは単純なWebsocketの実装です。このために使用できます koush/AndroidAsync ライブラリ

このプロジェクトをプロジェクトに実装する

    dependencies {
    compile 'com.koushikdutta.async:androidasync:2.+'
}

次に、Websocketサーバーに接続します

 String url="ws://172.17.1.54:8000/";
    AsyncHttpClient.getDefaultInstance().websocket(url, "my-protocol", new WebSocketConnectCallback() {
        @Override
        public void onCompleted(Exception ex, WebSocket webSocket) {
            if (ex != null) {
                ex.printStackTrace();
                return;
            }

            webSocket.setStringCallback(new StringCallback() {
                public void onStringAvailable(String s) {
                    System.out.println("I got a string: " + s);
                }
            });
            webSocket.setDataCallback(new DataCallback() {
                public void onDataAvailable(DataEmitter emitter, ByteBufferList byteBufferList) {
                    System.out.println("I got some bytes!");
                    // note that this data has been read
                    byteBufferList.recycle();
                }
            });
        }
    });

ここで、setStringCallback()とsetDataCallback()がリアルタイムの更新を受け取ります。

これには codebutler/Android-websockets ライブラリを使用することもできます。

解決策2:Stomp実装を使用する

これには、 Gozirra Javaライブラリを使用してこの問題を解決できます。 ダウンロード クライアントライブラリを使用できます。次に、libsフォルダに配置します。

サーバーに接続するため

 Client c = new Client("server url", port, "login", "password");

更新のリスナーを作成します

 Listener listener=new Listener() {
            @Override
            public void message(Map map, String s) {
                //Do your stuff
            }
        };

次に、トピックメッセージを購読します

 c.subscribe("foo-channel", listener);

登録を解除したい場合は、以下のコードを使用できます

  c.unsubscribe("foo-channel", listener);  // Unsubscribe only one listener

または

 c.unsubscribe("foo-channel");   // Unsubscribe all listeners

クライアントを切断するため

c.disconnect();

実サーバーではテストしていませんが、うまくいくと思います。問題が解決するかどうか教えてください。

解決策3

あなたがライブラリについて言及しているように https://github.com/NaikSoftware/StompProtocolAndroid これを使用できます。簡略化バージョンは次のとおりです

プロジェクトレベルのgradleにmavenリンクを追加します

  repositories {
        maven { url "https://jitpack.io" }
    }

モジュールレベルのgradleに依存関係を追加する

 implementation 'com.github.NaikSoftware:StompProtocolAndroid:1.1.5'
 implementation 'org.Java-websocket:Java-WebSocket:1.3.0'

次に、次のコードを使用してメッセージを取得します

 StompClient mStompClient = Stomp.over(WebSocket.class, "ws://10.0.2.2:5000/");


    mStompClient.topic("/topic/general").subscribe(new Action1<StompMessage>() {
        @Override
        public void call(StompMessage stompMessage) {
            Log.e(TAG, stompMessage.getPayload());
        }
    });
    mStompClient.lifecycle().subscribe(new Action1<LifecycleEvent>() {
        @Override
        public void call(LifecycleEvent lifecycleEvent) {
            switch (lifecycleEvent.getType()) {

                case OPENED:
                    Log.e(TAG, "Stomp connection opened");
                    break;

                case ERROR:
                    Log.e(TAG, "Error", lifecycleEvent.getException());
                    break;

                case CLOSED:
                    Log.e(TAG, "Stomp connection closed");
                    break;
            }
        }
    });
    mStompClient.connect();
7
Vinayak B

SquareのOkHttpライブラリを使用します。

この依存関係をビルドgradleに追加します

implementation 'com.squareup.okhttp3:okhttp:3.10.0'

ウェブショックを聞くために以下のクラスを使用してください

public class SocketListner extends WebSocketListener {

    private Mediator mediator;

    private static final int CLOSURE_STATUS = 1000;
    private WebSocket webSocket = null;

    public SocketListner(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void onOpen(WebSocket webSocket, Response response) {
        super.onOpen(webSocket, response);
        this.webSocket = webSocket;
        mediator.onConnected(webSocket, response);
    }

    public void sendMsg(String msg) {
        if (webSocket != null)
            webSocket.send(msg);
    }

    @Override
    public void onFailure(WebSocket webSocket, Throwable t, @Nullable Response response) {
        mediator.onFailure(webSocket, t.getLocalizedMessage());
        AppCons.printTag("Failure :", t.getMessage());
    }

    @Override
    public void onClosed(WebSocket webSocket, int code, String reason) {
        mediator.closingOrClosed(true, webSocket, reason, code);
        AppCons.printTag("Closed :", reason);
    }

    @Override
    public void onClosing(WebSocket webSocket, int code, String reason) {
        mediator.closingOrClosed(false, webSocket, reason, code);
        AppCons.printTag("Closing :", reason);
    }

    @Override
    public void onMessage(WebSocket webSocket, String text) {
        mediator.getMessage(text);
    }

    public interface Mediator {
        void onConnected(WebSocket webSocket, Response response);

        void getMessage(String msg);

        void onFailure(WebSocket webSocket, String reason);

        void closingOrClosed(boolean isClosed, WebSocket webSocket, String reason, int code);

    }

    public WebSocket getWebSocket() {
        return webSocket;
    }
}

ショックレットを介してデータにアクセスするには、以下のコードを使用してください

private OkHttpClient client;
private SocketListner listner;
private void startShocketConnection() {


    client = new OkHttpClient.Builder().readTimeout(3, TimeUnit.SECONDS).build();

    listner = new SocketListner(new SocketListner.Mediator() {
        @Override
        public void onConnected(WebSocket webSocket, Response response) {
            Log.d("Connected :", response.toString());
        }

        @Override
        public void getMessage(String msg) {
            try {
                Log.d("Received", msg);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(WebSocket webSocket, String reason) {
            //reconnect when failure with server
            Log.d("Failure :", reason);
        }

        @Override
        public void closingOrClosed(boolean isClosed, WebSocket webSocket, String reason, int code) {
            Log.d("ClosingOrClosed :", isClosed ? "Closed" : "closing");
        }
    });

    Request request = new Request.Builder()
            .url("your shocket url")
            .build();
    client.newWebSocket(request, listner);

}

private void closeSocket() {

        try {
            listner.getWebSocket().cancel();
            listner.getWebSocket().close(1000, "Good bye !");

            if ((response != null)) {
                client.dispatcher().executorService().shutdown();
                client.connectionPool().evictAll();
                response.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        response = null;
    }
6
Ranjan