Which WebSocket library to use in Android app?
I want to add a Service to my Android app which runs in the background holding a WebSocket connection (possibly over several hours or even days) and regularly sends some data to a server.
Now there seems to be a bunch of WebSocket libraries for Java, and I'm not sure which one I should use:
TooTallNate/Java-WebSocket Description from GitHub: A barebones WebSocket client and server implementation written in 100% Java. http://java-websocket.org/ -- This one is linked in my first result of googling "android websocket". However, it has quite a few open issues, especially about SSL connections, and it doesn't seem to be actively maintained at the moment.
koush/AndroidAsync Description from GitHub: Asynchronous socket, http (client+server), websocket, and socket.io library for android. Based on nio, not threads. -- Again many open issues, but seems to be activiley maintained/worked on.
Project Tyrus Description from Website: JSR 356: Java API for WebSocket - Reference Implementation -- This is made by Oracle. Not sure if it works in Android.
Jetty WebSocket Client API Info from Website: Jetty also provides a Jetty WebSocket Client Library to write make talking to WebSocket servers easier. -- Again: Not sure if it works in Android.
codebutler/android-websockets Description from GitHub: Bare minimum websockets (hybi13/RFC) client for Android -- This one is used in schwiz/android-websocket-example, which is the accepted answer for the StackOverflow-question "How to make the Android device hold a TCP connection to Internet without wake lock?".
Atmosphere/wasync Description from GitHub: WebSockets with fallback transports client library for Node.js, Android and Java http://async-io.org
TakahikoKawasaki/nv-websocket-client Description from GitHub: High-quality WebSocket client implementation in Java.
square/okhttp Description from GitHub: An HTTP+SPDY client for Android and Java applications. http://square.github.io/okhttp/ -- It has a Websocket module. As mentioned by scorpiodawg, OkHttp has built-in websocket support since version 3.5.
firebase/TubeSock Description from GitHub: A WebSocket client library implemented in Java
Autobahn|Android (GitHub) Description from Website: Autobahn|Android is an open-source networking library for Java/Android created by the Autobahn project that implements the WebSocket Protocol and the Web Application Messaging Protocol (WAMP) for creating native mobile WebSocket/WAMP clients. -- cloudsurfin pointed out that this has no support for wss.
In addition, there is a native socket.io client library for Android:
To use the socket.io Android client would be handy for me, because I plan to use nodejs/socket.io for the web frontend anyway. But the native client is quite young and has several open issues. And in addition to that, it is my understanding that an android app does not have any benefit of using the socket.io client library (apart from being compatible with socket.io 1.0 server), because WebSocket support can be assured at the client side.
My requirements are as follows:
Any suggestions which one is the right library for these requirements?
Some notes.
koush/AndroidAsync does not perform the closing handshake which is required by RFC 6455. See this for details.
Project Tyrus works on Android, but make sure that its license (CDDL 1.1 and GPL 2 with CPE) and its size (Reducing WebSocket client jar size with ProGuard) meet your requirements. Also note that Tyrus may throw an exception when a text size is large (it's probably a bug). See this for details.
Jetty : A 2-year-ago email thread in jetty-users mailing list says "We currently have no Android compatible Jetty 9 WebSocket client. There are plans to attempt to backport the Jetty WebSocket Client from JDK 7 to JDK 5/6 for android use, but its a lower priority than finishing our implementation of JSR-356 Java WebSocket API (javax.websocket)." Jetty's current document about its WebSocket Client API does not mention anything about Android.
codebutler/android-websocket does not perform the closing handshake which is required by RFC 6455 and may throw an exception on close. See this.
Atmosphere/wasync uses AsyncHttpClient/async-http-client as its WebSocket implementation. So, rather, AsyncHttpClient/async-http-client should be mentioned instead.
firebase/TubeSock does not verify Sec-WebSocket-Accept
. This is a violation against RFC 6455. Also, TubeSock has a bug in building a text message. You will encounter the bug sooner or later if you use multi-byte UTF-8 characters for text messages. See Issue 3 in delight-im/Android-DDP for a long list about TubeSock problems.
Consideration Points
Consideration points in selecting a WebSocket client implementation written in Java:
SSLSocketFactory
and SSLContext
should be able to be utilized without unnecessary restrictions. Socket.connect(SocketAddress endpoint, int timeout)
method) nv-websocket-client covers all the above except the last two. In addition, one of its small but convenient features is to send ping/pong frames periodically. It can be achieved just by calling setPingInterval
/ setPongInterval
methods (See JavaDoc).
Disclaimer: Takahiko Kawasaki is the author of nv-websocket-client.
Some other considerations:
Tyrus works on Android. However, the SSL libraries it uses in Android 5.0 are buggy and fail SSL handshakes. This is supposed to be fixed in newer versions of Android, but with the way that Android is not updated on many devices, this may be a problem for you.
Depending on how SSL is implemented for other websocket implementations, this may also be a problem.
AndroidAsync does not have this SSL issue. It does have other issues like not being able to set timeouts.
a) Add this file in gradle file
compile 'com.github.nkzawa:socket.io-client:0.3.0'
b) Add these lines in Application Activity:
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) Add this function to your activity, where you called 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/94600.html