Android 앱에서 사용할 WebSocket 라이브러리는 무엇입니까? [닫은]

WebSocket 연결을 유지하면서 (몇 시간 또는 며칠 이상) 백그라운드에서 실행 되며 정기적으로 서버에 일부 데이터를 보내는 내 Android 앱에 서비스 를 추가하고 싶습니다 .

이제 Java 용 WebSocket 라이브러리가 많이있는 것 같습니다. 어떤 라이브러리를 사용해야하는지 잘 모르겠습니다.

또한 Android 용 기본 socket.io 클라이언트 라이브러리가 있습니다.

  • nkzawa / socket.io-client.java
    GitHub의 설명 : Socket.IO v1.0 이상과 호환되는 Java 용 전 기능 Socket.IO 클라이언트 라이브러리.

어쨌든 웹 프론트 엔드에 nodejs / socket.io를 사용할 계획이기 때문에 socket.io Android 클라이언트를 사용하는 것이 편리합니다. 그러나 네이티브 클라이언트는 상당히 어리고 몇 가지 공개 된 문제가 있습니다. 또한 WebSocket 지원이 클라이언트 측에서 보장 될 수 있기 때문에 안드로이드 앱이 socket.io 클라이언트 라이브러리 (socket.io 1.0 서버와 호환되는 것을 제외하고)를 사용하는 이점이 없다는 것을 이해합니다. .

내 요구 사항은 다음과 같습니다.

  • Android API 9 이상과의 호환성
  • SSL을 통한 연결 가능성
  • 영구적 인 깨우기 잠금을 유지하지 않고도 오랫동안 연결 유지
  • 사용 가능한 nodejs websocket 서버 구현 또는 socket.io와의 호환성

이러한 요구 사항에 적합한 라이브러리 중 어떤 것이 있습니까?



답변

몇 가지 메모.

  • koush / AndroidAsyncRFC 6455에 필요한 닫기 핸드 셰이크 를 수행하지 않습니다 . 자세한 내용은 이것을 참조 하십시오.

  • Project Tyrus 는 Android에서 작동하지만 라이센스 ( CDL이 포함 된 CDDL 1.1 및 GPL 2 ) 및 크기 ( ProGuard로 WebSocket 클라이언트 jar 크기 줄이기 )가 요구 사항을 충족하는지 확인하십시오. 또한 텍스트 크기가 크면 Tyrus에서 예외가 발생할 수 있습니다 (버그 일 수 있음). 자세한 내용은 이것을 참조 하십시오.

  • Jetty : 부두 사용자 메일 링리스트 의 2 년 전 이메일 스레드“현재 Android 호환 Jetty 9 WebSocket 클라이언트가 없습니다. Android 용 Jetty WebSocket 클라이언트를 JDK 7에서 JDK 5/6으로 백 포트 할 계획이 있습니다. JSR-356 Java WebSocket API (javax.websocket) 구현을 완료하는 것보다 우선 순위가 낮습니다. ” WebSocket Client API에 대한 Jetty의 현재 문서 에는 Android에 대한 언급이 없습니다.

  • codebutler / android-websocketRFC 6455에 필요한 닫기 핸드 셰이크 를 수행하지 않으며 닫기시 예외를 throw 할 수 있습니다. 참조 .

  • Atmosphere / wasyncAsyncHttpClient / 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 클라이언트 구현을 선택할 때 고려해야 할 사항 :

  1. 준수 . RFC 6455에 필요한 클로징 핸드 셰이크를 구현하는 것은 소수의 구현이 아닙니다 . (닫는 악수를 구현하지 않을 경우 어떻게됩니까?를 참조하십시오 .)
  2. 필수 Java 버전 . Java SE 5, 6, 7, 8 또는 Java EE? 안드로이드에서도 작동합니까?
  3. 크기 . 일부 구현에는 많은 종속성이 있습니다.
  4. wss 지원.
  5. HTTP 프록시 지원
  6. HTTP 프록시 지원을 통한 WSSS . HTTP 프록시를 통한 wss를 지원하기 위해 WebSocket 클라이언트 라이브러리가 수행해야하는 작업에 대해서는 HTML5 웹 소켓이 프록시 서버와 상호 작용하는 방법의 그림 2를 참조하십시오 .
  7. SSL 구성에 대한 유연성 . SSLSocketFactorySSLContext불필요한 제한없이 활용 될 수 있어야한다.
  8. 기본 인증을 포함 하여 오프닝 핸드 셰이크 의 사용자 정의 HTTP 헤더
  9. 프록시 서버에서의 인증을 포함하여 HTTP 프록시 협상의 사용자 정의 HTTP 헤더
  10. 모든 프레임 유형 (연속, 이진, 텍스트, 닫기, 핑 및 탁구) 을 보낼 수 있습니다 . 대부분의 구현은 개발자에게 조각난 프레임요청하지 않은 퐁 프레임을 수동으로 보내는 수단을 제공하지 않습니다 .
  11. 다양한 WebSocket 이벤트를 수신하기위한 리스너 인터페이스 . 인터페이스가 열악하면 개발자가 좌절합니다. 풍부한 인터페이스를 통해 개발자는 강력한 응용 프로그램을 작성할 수 있습니다.
  12. WebSocket 상태를 조회 할 수 있습니다. RFC 6455 는 CONNECTING, OPEN, CLOSING 및 CLOSED 상태를 정의하지만 정의 된 방식으로 내부 상태 전이를 유지하는 구현은 거의 없습니다.
  13. 소켓 연결에 대한 시간 초과 값을 설정할 수 있습니다 . ( 방법 의 두 번째 인수와 동일 )Socket.connect(SocketAddress endpoint, int timeout)
  14. 기본 원시 소켓에 액세스 할 수 있습니다 .
  15. 사용하기 쉬운 직관적 API .
  16. 문서화 여부
  17. RFC 7692 (WebSocket 용 압축 확장) 지원 (일명 permessage-deflate).
  18. 리디렉션 (3xx) 지원
  19. 다이제스트 인증 지원.

nv-websocket-client 는 마지막 두 개를 제외한 위의 모든 것을 다룹니다. 또한 작지만 편리한 기능 중 하나는 핑 / 퐁 프레임을 주기적으로 보내는 것입니다. setPingInterval/setPongInterval메소드를 호출하여 수행 할 수 있습니다( JavaDoc 참조).

면책 조항 : Takahiko Kawasaki는 nv-websocket-client의 저자입니다.


답변

다른 고려 사항 :

Tyrus는 Android에서 작동합니다. 그러나 Android 5.0에서 사용하는 SSL 라이브러리는 버그가 있으며 SSL 핸드 셰이크에 실패합니다 . 이것은 최신 버전의 Android에서 수정되어야하지만 Android가 많은 기기에서 업데이트되지 않는 방식으로 인해 문제가 될 수 있습니다.

다른 웹 소켓 구현에 SSL이 구현되는 방식에 따라 문제가 될 수도 있습니다.

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


            });
        }
    };