Какую библиотеку WebSocket использовать в приложении Android?
Я хочу добавить Service в мое приложение для Android, которое работает в фоновом режиме с WebSocket (возможно, в течение нескольких часов или даже дней) и регулярно отправляет некоторые данные на сервер.
Теперь для Java существует куча библиотек WebSocket, и я не уверен, какой из них я должен использовать:
-
TooTallNate/Java-WebSocket
Описание от GitHub: Баботированная версия клиента и сервера WebSocket, написанная на 100% Java. http://java-websocket.org/
- Этот связанный в мой первый результат googling "android websocket" . Тем не менее, у него есть довольно много открытых вопросов, особенно о SSL-соединениях, и в настоящее время он, похоже, активно не поддерживается.
-
koush/AndroidAsync
Описание от GitHub: асинхронный сокет, http (клиент + сервер), websocket и библиотека socket.io для Android. На основе nio, а не потоков.
- Опять много открытых вопросов, но, похоже, они поддерживаются и работают.
-
Проект Tyrus
Описание с сайта: JSR 356: API Java для WebSocket - Реализация ссылок
- Это сделано Oracle. Не уверен, работает ли он на Android.
-
API клиента Jetty WebSocket
Информация с веб-сайта: Jetty также предоставляет клиентскую библиотеку Jetty WebSocket, чтобы упростить работу с серверами WebSocket.
- Снова: не уверен, работает ли он на Android.
-
codebutler/android-websockets
Описание от GitHub: Минимальные веб-интерфейсы (hybi13/RFC) для Android
- Этот используется в schwiz/android-websocket-example, который является принятым ответом на вопрос StackOverflow Как заставить Android-устройство поддерживать TCP-соединение с Интернетом без блокировки слежения? ".
-
Atmosphere/wasync
Описание от GitHub: WebSockets с резервной передачей клиентской библиотеки для Node.js, Android и Java http://async-io.org
-
TakahikoKawasaki/nv-websocket-client
Описание от GitHub: Высококачественная реализация клиента WebSocket на Java.
-
square/okhttp
Описание от GitHub: клиент HTTP + SPDY для приложений Android и Java. http://square.github.io/okhttp/
- У него есть Websocket module. Как упомянутый scorpiodawg, OkHttp имеет встроенную поддержку websocket с версии 3.5.
-
firebase/TubeSock
Описание из GitHub: клиентская библиотека WebSocket, реализованная в Java
-
Autobahn | Android (GitHub)
Описание с сайта: Autobahn | Android - это сетевая библиотека с открытым исходным кодом для Java/Android, созданная проектом Autobahn, которая реализует протокол WebSocket и протокол обмена сообщениями веб-приложений (WAMP) для создания собственных мобильных клиентов WebSocket/WAMP. - pointurfin указал, что это не поддерживает wss.
Кроме того, существует родная socket.io клиентская библиотека для Android:
- nkzawa/socket.io-client.java
Описание от GitHub: полнофункциональная клиентская библиотека Socket.IO для Java, совместимая с Socket.IO v1.0 и новее.
Чтобы использовать клиент сокета socket.io, мне было бы удобно, потому что я планирую использовать nodejs/socket.io для веб-интерфейса в любом случае. Но родной клиент довольно молод и имеет несколько открытых проблем. И в дополнение к этому, я понимаю, что приложение для Android не имеет никакой пользы от использования клиентской библиотеки socket.io(кроме совместимости с сервером socket.io 1.0), поскольку поддержка WebSocket может быть обеспечена на стороне клиента.
Мои требования следующие:
- Совместимость с Android API 9 и выше
- Возможность подключения через SSL
- Держите соединение в течение длительного времени без необходимости держать постоянный wakelock
- Совместимость с доступной версией сервера websocket nodejs или с socket.io
Любые предложения, которые являются правильной библиотекой для этих требований?
Ответы
Ответ 1
Некоторые заметки.
-
koush/AndroidAsync не выполняет закрытие рукопожатия, которое требуется RFC 6455. Подробнее см. .
-
Проект Tyrus работает на Android, но убедитесь, что его лицензия (CDDL 1.1 и GPL 2 с CPE) и его размер (Уменьшение размера банка клиента WebSocket с помощью ProGuard) соответствуют вашим требованиям. Также обратите внимание, что Tyrus может генерировать исключение, когда размер текста большой (это, вероятно, ошибка). Подробнее см. .
-
Jetty: 2-летняя почтовая нить в списке рассылки пользователей причала говорит: В настоящее время у нас нет Android-совместимого клиента Jetty 9 WebSocket. Планируется попытаться выполнить резервное копирование Jetty WebSocket Client с JDK 7 на JDK 5/6 для использования в Android, но его более низкий приоритет, чем завершение нашей реализации JSR-356 Java WebSocket API (javax.websocket) ". Jetty current document о своем API-интерфейсе WebSocket Client ничего не упоминает об Android.
-
codebutler/android-websocket не выполняет закрытие рукопожатия, которое требуется RFC 6455 и может вызывать исключение при закрытии. См. .
-
Атмосфера /wasync использует AsyncHttpClient/async-http-client как ее Реализация WebSocket. Поэтому вместо этого следует упомянуть AsyncHttpClient/async-http-client.
-
firebase/TubeSock не проверяет Sec-WebSocket-Accept
. Это является нарушением RFC 6455. Кроме того, TubeSock имеет ошибку при построении текстового сообщения. Вы будете сталкиваться с ошибкой рано или поздно, если вы используете многобайтовые символы UTF-8 для текстовых сообщений. См. Проблема 3 в delight-im/Android-DDP для длинного списка Проблемы с TubeSock.
Точки рассмотрения
Точки рассмотрения при выборе клиентской реализации WebSocket, написанные на Java:
- Соответствие. Не небольшое количество реализаций не реализует закрытие рукопожатия, требуемое RFC 6455. (Что произойдет, если закрытие рукопожатия не реализовано? См. this.)
- Требуемая версия Java. Java SE 5, 6, 7, 8 или Java EE? Работает даже на Android?
- Размер. Некоторые реализации имеют много зависимостей.
- wss.
- поддержка HTTP прокси.
- поддержка wss через HTTP прокси. См. Рисунок 2 в Как HTML5 Web Sockets взаимодействуют с прокси-серверами о том, что должна делать клиентская библиотека WebSocket для поддержки wss через HTTP-прокси.
- Гибкость при настройке SSL.
SSLSocketFactory
и SSLContext
должны быть использованы без лишних ограничений.
- Пользовательские заголовки HTTP в открытие рукопожатия, включая основную проверку подлинности.
- Пользовательские заголовки HTTP в согласовании HTTP-прокси, включая проверку подлинности на прокси-сервере.
- Возможность отправки всех типов фреймов (продолжение, двоичный, текст, закрыть, пинг и понг) или нет. Большинство реализаций не предоставляют разработчикам средства для отправки фрагментированных фреймов и незатребованных теннисных рам вручную.
- Интерфейс прослушивателя для получения различных событий WebSocket. Плохой интерфейс заставляет разработчиков расстраиваться. Богатый интерфейс помогает разработчикам писать надежные приложения.
- Возможность запросить состояние WebSocket или нет. RFC 6455 определяет состояния CONNECTING, OPEN, CLOSING и CLOSED, но несколько реализаций поддерживают свой внутренний переход состояния определенным образом.
- Возможность установки значения таймаута для подключения сокета. (Эквивалентно второму аргументу метода
Socket.connect(SocketAddress endpoint, int timeout)
)
- Возможность доступа к базовому сырым сокетам.
- Интуитивно понятный простой в использовании API или нет.
- Хорошо документированный или нет.
- RFC 7692 (Расширения сжатия для WebSocket) поддержка (aka permessage-deflate).
- Перенаправление (3xx).
- Поддержка дайджест-аутентификации.
nv-websocket-client охватывает все вышеперечисленное, кроме последних двух. Кроме того, одна из его небольших, но удобных функций - периодически отправлять кадры ping/pong. Это может быть достигнуто только путем вызова методов setPingInterval
/setPongInterval
(см. JavaDoc).
Отказ от ответственности: Такахико Кавасаки является автором nv-websocket-клиента.
Ответ 2
Некоторые другие соображения:
Тирус работает на Android. Тем не менее, библиотеки SSL, которые он использует в Android 5.0, являются ошибками и завершают SSL-подтверждения. Предполагается, что это исправлено в новых версиях Android, но с тем, что Android не обновляется на многих устройствах, это может быть проблемой для вас.
В зависимости от того, как SSL реализован для других реализаций websocket, это также может быть проблемой.
В AndroidAsync нет этой проблемы с SSL. У него есть другие проблемы, такие как неспособность установить тайм-ауты.
Ответ 3
a) Добавьте этот файл в файл gradle
compile 'com.github.nkzawa: socket.io-client: 0.3.0'
b) Добавьте эти строки в 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 in 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(() -> {
});
}
};