哪个WebSocket库在Android应用程序中使用?

我想添加一个服务到我的Android应用程序,该应用程序在后台运行,持有WebSocket连接(可能需要几个小时甚至几天),并定期将一些数据发送到服务器。

现在似乎有一堆用于Java的WebSocket库,我不确定我应该使用哪一个:

  • 来自GitHub的TooTallNate / Java-WebSocket描述:用100%Java编写的准系统WebSocket客户端和服务器实现。 http://java-websocket.org/ - 这是我的第一个搜索结果谷歌搜索“android websocket”。 但是,它有很多悬而未决的问题,特别是关于SSL连接的问题,目前似乎没有得到积极维护。

  • koush / AndroidAsync来自GitHub的描述: android的异步套接字,http(client + server),websocket和socket.io库。 基于nio,不是线程。 - 还有很多未解决的问题,但似乎是维护/正在开展的活动。

  • 项目Tyrus来自网站的描述:JSR 356:WebSocket的Java API - 参考实现 - 这是由Oracle制定的。 不知道它是否适用于Android。

  • 来自网站的Jetty WebSocket客户端API信息:Jetty还提供了一个Jetty WebSocket客户端库,以便于与WebSocket服务器交谈。 - 再次:不确定它是否适用于Android。

  • codebutler / android-websockets来自GitHub的描述:适用于Android的最小websockets(hybi13 / RFC)客户端 - 这一个用于schwiz / android-websocket-example,这是StackOverflow接受的答案 - 问题“如何使Android设备持有到Internet的TCP连接而无需唤醒锁定?“。

  • GitHub的Atmosphere / wasync描述:带有后备传输客户端库的WebSockets,用于Node.js,Android和Java http://async-io.org

  • TakahikoKawasaki / nv-websocket-client来自GitHub的描述:Java中的高质量WebSocket客户端实现。

  • square / okhttp来自GitHub的描述:适用于Android和Java应用程序的HTTP + SPDY客户端。 http://square.github.io/okhttp/ - 它有一个WebSocket模块。 正如scorpiodawg所提到的,OkHttp从3.5版本开始就内置websocket支持。

  • 来自GitHub的firebase / TubeSock描述:用Java实现的WebSocket客户端库

  • Autobahn | Android(GitHub)来自网站的描述:Autobahn | Android是由Autobahn项目创建的Java / Android开源网络库,它实现了WebSocket协议和Web应用程序消息协议(WAMP),用于创建本地移动WebSocket / WAMP客户端。 - cloudsurfin指出,这不支持wss。

  • 另外,还有一个适用于Android的本地socket.io客户端库:

  • nkzawa / socket.io-client.java来自GitHub的描述:功能齐全的Socket.IO Client Library for Java,它与Socket.IO v1.0及更高版本兼容。
  • 要使用socket.io Android客户端对我来说很方便,因为我打算使用nodejs / socket.io作为web前端。 但本地客户非常年轻,有几个未解决的问题。 除此之外,我的理解是,android应用程序没有任何使用socket.io客户端库的优点(除了与socket.io 1.0服务器兼容外),因为可以在客户端确保WebSocket支持。

    我的要求如下:

  • 与Android API 9及更高版本兼容
  • 可以通过SSL连接
  • 保持连接很长一段时间,而不必持有永久性的唤醒锁
  • 与可用的nodejs websocket服务器实现或socket.io兼容
  • 任何建议哪一个是适合这些要求的正确库?


    一些笔记。

  • koush / AndroidAsync不执行RFC 6455所要求的关闭握手。请参阅此处了解详细信息。

  • Project Tyrus适用于Android,但要确保其许可证(带有CPE的CDDL 1.1和GPL 2)及其大小(使用ProGuard减少WebSocket客户端jar大小)符合您的要求。 还要注意,当文字大小很大时(这可能是一个错误),Tyrus可能会抛出异常。 详情请参阅此。

  • JettyJetty用户邮件列表中的一个2年前的电子邮件主题说:“我们目前没有与Android兼容的Jetty 9 WebSocket客户端。有计划尝试将Jetty WebSocket客户端从JDK 7反向移植到JDK 5/6 for android使用,但它的优先级低于完成我们的JSR-356 Java WebSocket API(javax.websocket)的实现。“ Jetty目前关于其WebSocket客户端API的文档没有提及任何关于Android的内容。

  • codebutler / android-websocket不执行RFC 6455要求的关闭握手,并可能在关闭时引发异常。 看到这个。

  • Atmosphere / wasync使用AsyncHttpClient / async-http-client作为其WebSocket实现。 所以,应该提到AsyncHttpClient / async-http-client。

  • firebase / TubeSock不验证Sec-WebSocket-Accept 。 这是对RFC 6455的违规。另外,TubeSock在构建文本消息时存在一个错误。 如果您对短信使用多字节UTF-8字符,则迟早会遇到该错误。 有关TubeSock问题的详细列表,请参阅delight-im / Android-DDP中的第3期。

  • 考虑点

    在选择用Java编写的WebSocket客户端实现时需要考虑的几点:

  • 合规 。 不少的实现不实现RFC 6455要求的关闭握手。(如果关闭握手未实现,会发生什么情况?请参阅此处。)
  • 必需的Java版本 。 Java SE 5,6,7,8或Java EE? 甚至在Android上工作?
  • 大小 。 有些实现有很多依赖关系。
  • wss支持。
  • HTTP代理支持。
  • 通过HTTP代理支持。 请参阅HTML5 Web套接字与代理服务器的交互方式中的图2,了解WebSocket客户端库如何支持wss over HTTP代理。
  • 灵活的SSL配置 。 应该可以使用SSLSocketFactorySSLContext ,而没有不必要的限制。
  • 在开始的握手中定制HTTP标头 ,包括基本认证。
  • HTTP代理协商中的自定义HTTP头 ,包括代理服务器上的身份验证。
  • 能够发送所有帧类型 (连续,二进制,文本,关闭,乒乓和乒乓)或不。 大多数实现不会为开发人员提供手动发送碎片帧和未经请求的pong帧的方法。
  • 监听器接口接收各种WebSocket事件。 糟糕的界面让开发人员感到沮丧。 丰富的界面可帮助开发人员编写强大的应用
  • 能够查询WebSocket状态与否。 RFC 6455定义了CONNECTING,OPEN,CLOSING和CLOSED状态,但很少有实现以定义的方式维护其内部状态转换。
  • 能够为套接字连接设置超时值 。 (相当于Socket.connect(SocketAddress endpoint, int timeout)方法的第二个参数)
  • 能够访问底层原始套接字
  • 直观易用的API或不。
  • 记录良好或没有。
  • RFC 7692(支持WebSocket的压缩扩展)支持(又称渗透 - 放气)。
  • 重定向 (3xx)支持。
  • 摘要认证支持。
  • nv-websocket-client涵盖了除了最后两个以外的所有内容。 另外,它的一个小而方便的功能是定期发送ping / pong帧。 它可以通过调用setPingInterval / setPongInterval方法来实现(请参阅JavaDoc)。

    免责声明:Takahiko Kawasaki是nv-websocket-client的作者。


    其他一些考虑:

    Tyrus适用于Android。 但是,它在Android 5.0中使用的SSL库存在漏洞,并且无法通过SSL握手。 这应该在Android的新版本中得到解决,但是Android的许多设备没有更新Android的方式,这对您来说可能是个问题。

    根据SSL如何实现其他websocket实现,这可能也是一个问题。

    AndroidAsync没有这个SSL问题。 它确实有其他问题,如不能设置超时。


    a)将该文件添加到gradle文件中

    compile 'com.github.nkzawa:socket.io-client:0.3.0'

    b)在应用程序活动中添加这些行:

        public class MyApplication extends Application {
         private Socket mSocket;
            {
                try {
                   mSocket = IO.socket(Config.getBaseURL());
    
                } catch (URISyntaxException e) {
                    throw new RuntimeException(e);
                }
            }
    
            public Socket getSocket() {
                return mSocket;
            }
    }
    

    c)将此函数添加到您称为WebSocket的活动中:

         private void websocketConnection() {
                //Get websocket from application
                MyApplication app = (MyApplication ) getApplication();
                mSocket = app.getSocket();
                mSocket.on(Socket.EVENT_CONNECT, onConnect);
                mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
                mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
                mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
                mSocket.on("messageFromServer", onNewLocation);
                mSocket.connect();
            } 
    
    
        private Emitter.Listener onConnect = new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                runOnUiThread(() -> {
                    if (!isConnected) {
    
                        RequestSocket mRequestSocket = new RequestSocket();
    
                        mRequestSocket.setToken("anil_singhania");
                       /* your parameter */
                        mSocket.emit("messageFromClient", new Gson().toJson(mRequestSocket));
                        Log.i("Socket Data", new Gson().toJson(mRequestSocket));
                        isConnected = true;
                    }
                });
            }
        };
    
        private Emitter.Listener onDisconnect = args -> runOnUiThread(() -> {
            isConnected = false;
           /* Toast.makeText(getApplicationContext(),
                    R.string.disconnect, Toast.LENGTH_LONG).show();*/
        });
    
        private Emitter.Listener onConnectError = args -> runOnUiThread(() -> {
             /*   Toast.makeText(getApplicationContext(),
                R.string.error_connect, Toast.LENGTH_LONG).show()*/
        });
    
        private Emitter.Listener onNewLocation = new Emitter.Listener() {
            @Override
            public void call(final Object... args) {
                runOnUiThread(() -> {
    
    
                });
            }
        };
    
    链接地址: http://www.djcxy.com/p/94599.html

    上一篇: Which WebSocket library to use in Android app?

    下一篇: losing reference to the socket in socket.io