Какую библиотеку WebSocket использовать в приложении Android? - программирование
Подтвердить что ты не робот

Какую библиотеку 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

Любые предложения, которые являются правильной библиотекой для этих требований?

4b9b3361

Ответ 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(() -> {


            });
        }
    };