WebSocket 연결을 유지하면서 (몇 시간 또는 며칠 이상) 백그라운드에서 실행 되며 정기적으로 서버에 일부 데이터를 보내는 내 Android 앱에 서비스 를 추가하고 싶습니다 .
이제 Java 용 WebSocket 라이브러리가 많이있는 것 같습니다. 어떤 라이브러리를 사용해야하는지 잘 모르겠습니다.
-
GitHub의 TooTallNate / Java-WebSocket 설명 : 100 % Java로 작성된 기본 WebSocket 클라이언트 및 서버 구현입니다. http://java-websocket.org/-
이것은 “android websocket”인터넷 검색의 첫 번째 결과 와 연결되어 있습니다 . 그러나 특히 SSL 연결과 관련하여 몇 가지 공개 문제가 있으며 현재 적극적으로 유지 관리되지 않는 것 같습니다. -
koush / AndroidAsync
GitHub의 설명 : 비동기 소켓, http (클라이언트 + 서버), 웹 소켓 및 Android 용 socket.io 라이브러리. 스레드가 아닌 nio를 기반으로합니다. -다시 많은 공개 이슈가 있지만, 활동적으로 유지 보수 / 작업중인 것 같습니다. -
웹 사이트의 프로젝트 Tyrus 설명 : JSR 356 : WebSocket 용 Java API-참조 구현-Oracle에서 작성합니다. Android에서 작동하는지 확실하지 않습니다. -
웹 사이트의 Jetty WebSocket 클라이언트 API 정보 : Jetty는 또한 WebSocket 서버와 쉽게 대화 할 수 있도록 Jetty WebSocket 클라이언트 라이브러리를 제공합니다. -다시 : Android에서 작동하는지 확실하지 않습니다. -
codebutler / android-websockets
GitHub의 설명 : Android 용 Bare Minimum Websockets (hybi13 / RFC) 클라이언트-이것은 schwiz / android-websocket-example 에서 사용되며, 이는 StackOverflow-question에 허용되는 답변입니다 . Android 기기에서 깨우기 잠금없이 인터넷에 대한 TCP 연결을 유지 하시겠습니까? “. -
GitHub의 대기 / wasync 설명 : Node.js, Android 및 Java 용 폴백 전송 클라이언트 라이브러리가있는 WebSocket http://async-io.org -
TakahikoKawasaki / nv-websocket-client
GitHub의 설명 : Java의 고품질 WebSocket 클라이언트 구현. -
square / okhttp
GitHub의 설명 : Android 및 Java 애플리케이션을위한 HTTP + SPDY 클라이언트. http://square.github.io/okhttp/
–그것은이 웹 소켓 모듈을 .으로 scorpiodawg 언급 , OkHttp은 내장 된 웹 소켓 지원 버전 3.5 있기 때문이다. -
GitHub의 firebase / TubeSock 설명 : Java로 구현 된 WebSocket 클라이언트 라이브러리 -
Autobahn | Android ( GitHub )
웹 사이트 설명 : Autobahn | Android는 기본 모바일 WebSocket / WAMP를 생성하기 위해 WebSocket 프로토콜 및 웹 애플리케이션 메시징 프로토콜 (WAMP)을 구현하는 Autobahn 프로젝트에 의해 생성 된 Java / Android 용 오픈 소스 네트워킹 라이브러리입니다. 고객. – cloudsurfin는 지적 이 WSS을 지원하지 않는다는 점.
또한 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 / AndroidAsync 는 RFC 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-websocket 은 RFC 6455에 필요한 닫기 핸드 셰이크 를 수행하지 않으며 닫기시 예외를 throw 할 수 있습니다. 참조 이 .
-
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? 안드로이드에서도 작동합니까?
- 크기 . 일부 구현에는 많은 종속성이 있습니다.
- wss 지원.
- HTTP 프록시 지원
- HTTP 프록시 지원을 통한 WSSS . HTTP 프록시를 통한 wss를 지원하기 위해 WebSocket 클라이언트 라이브러리가 수행해야하는 작업에 대해서는 HTML5 웹 소켓이 프록시 서버와 상호 작용하는 방법의 그림 2를 참조하십시오 .
- SSL 구성에 대한 유연성 .
SSLSocketFactory
및SSLContext
불필요한 제한없이 활용 될 수 있어야한다. - 기본 인증을 포함 하여 오프닝 핸드 셰이크 의 사용자 정의 HTTP 헤더
- 프록시 서버에서의 인증을 포함하여 HTTP 프록시 협상의 사용자 정의 HTTP 헤더
- 모든 프레임 유형 (연속, 이진, 텍스트, 닫기, 핑 및 탁구) 을 보낼 수 있습니다 . 대부분의 구현은 개발자에게 조각난 프레임 과 요청하지 않은 퐁 프레임을 수동으로 보내는 수단을 제공하지 않습니다 .
- 다양한 WebSocket 이벤트를 수신하기위한 리스너 인터페이스 . 인터페이스가 열악하면 개발자가 좌절합니다. 풍부한 인터페이스를 통해 개발자는 강력한 응용 프로그램을 작성할 수 있습니다.
- WebSocket 상태를 조회 할 수 있습니다. RFC 6455 는 CONNECTING, OPEN, CLOSING 및 CLOSED 상태를 정의하지만 정의 된 방식으로 내부 상태 전이를 유지하는 구현은 거의 없습니다.
- 소켓 연결에 대한 시간 초과 값을 설정할 수 있습니다 . ( 방법 의 두 번째 인수와 동일 )
Socket.connect(SocketAddress endpoint, int timeout)
- 기본 원시 소켓에 액세스 할 수 있습니다 .
- 사용하기 쉬운 직관적 API .
- 문서화 여부
- RFC 7692 (WebSocket 용 압축 확장) 지원 (일명 permessage-deflate).
- 리디렉션 (3xx) 지원
- 다이제스트 인증 지원.
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(() -> {
});
}
};