【问题标题】:Suggest me to retrieve real time data from websocket server [closed]建议我从 websocket 服务器检索实时数据 [关闭]
【发布时间】:2018-10-24 10:22:29
【问题描述】:

我目前正在从事一个基于 GPS 的项目,我目前正在使用 volley 从网络接收数据,但最近他们计划使用实时数据升级服务。因此,Web 开发人员使用 websocket 对服务器进行了编程,对于他们所说的浏览器应用程序,他们使用 stomp.js 协议从服务器检索数据。他们要求我使用任何方式从他们的服务器(实时数据)中检索数据,但我不知道从 websocket 获取实时数据的最佳方法是什么。我从 github https://github.com/NaikSoftware/StompProtocolAndroid 找到了一个示例,但这对我来说还不够学习,并且互联网上使用 stomp 的文档也不够。我希望在android中可以有更好的实现。

如有任何帮助和建议,我们将不胜感激。请不要提到我 firebase,因为我已经提到过他们关于 firebase 的事情,他们拒绝使用它。请大家帮助我,建议我或给我一个很好的例子来简单地使用 volley 从 websocket 服务器检索数据..

【问题讨论】:

  • , I was using volley to parse the data from web ??? Volley 不解析数据。 Volley 只是向网络发送或从网络接收数据。请重新表述您的问题,因为您不止一次使用了 parse 这个词。
  • @greenapps 对不起我的英语不好!!
  • 服务器如何与客户端通信。是主题明智的沟通还是只是消息传递?
  • @VinayakB 只是消息传递,简而言之,数据从服务器传递到客户端和客户端需要打印数据的一种方式。就这样。帮帮我
  • 好的。在那种情况下,我会为你写 2 个答案。踩踏特定和正常的 websocket。请稍候

标签: android websocket stomp


【解决方案1】:

我的回答是基于这个问题中的 cmets。没有关于该问题的足够信息,因此我正在为您的问题编写 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 库来解决此问题。 您可以download 客户端库。然后将其放入您的 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 你可以使用这个。简化版如下

将 maven 链接添加到您的项目级 gradle 中

  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();

【讨论】:

  • 感谢您的回答,但我的网址是 192.168.1.76:8080/websocket-backend/socket/ 我需要订阅(/topic/notification") 但在解决方案 2 中我没有选项在端口之后传递/websocket-backend/socket/。第一个方法在onCompleted方法()处给我错误,错误“方法不会覆盖它的超类。”请帮帮我兄弟。我正在测试类似这里的服务器@987654326 @
  • 在第二个解决方案中将 192.168.1.76:8080/websocket-backend/socket/ 作为服务器 ip
  • 日志显示“Unknown url 192.168.1.76:8080/websocket-backend/socket”,例如我使用过类似 Client c = new Client("ws://192.168.1.76:8080/websocket -后端/socketl", 8080, null, null);我认为因为在这种情况下,我们的 url 将类似于 192.168.1.76:8080/websocket-backend/socket:8080 并再次订阅 url。 :P ,我尝试在第二个参数(端口)传递 null 但它是一个强制参数。先生,我能做什么?你能测试一下代码吗?
  • 试试 c = new Client("ws://192.168.1.76/websocket-backend/socket", 8080, null, null); .如果它不起作用,那么我会更新我的答案。
  • 没有兄弟,不工作,同样的错误“没有与主机名关联的地址”!!
【解决方案2】:

使用 Square 的 OkHttp 库。

将此依赖项添加到您的构建 gradle

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

使用下面的类来监听 webshockts

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;
    }
}

使用以下代码通过Shocket访问数据

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;
    }

【讨论】:

  • 感谢您抽出宝贵时间回答,我会尽快查看并回复! ;)
  • 我已经编辑了我的ans,因为我忘了提供关闭套接字。
  • 不工作兄弟.. 这段代码是否经过测试?我有任何错误。
  • 是的,我在我的应用程序中使用过。
  • 如果你有任何服务器ip然后告诉我,我很乐意提供帮助,同时你可以查看这个链接了解详细知识googleweblight.com/i?u=https://medium.com/@ssaurel/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多