Pustaka WebSocket mana yang digunakan dalam aplikasi Android? [Tutup]

131

Saya ingin menambahkan Layanan ke aplikasi Android saya yang berjalan di latar belakang memegang koneksi WebSocket (mungkin lebih dari beberapa jam atau bahkan berhari-hari) dan secara teratur mengirimkan beberapa data ke server.

Sekarang tampaknya ada banyak perpustakaan WebSocket untuk Java, dan saya tidak yakin yang mana yang harus saya gunakan:

Selain itu, ada perpustakaan klien socket.io asli untuk Android:

Untuk menggunakan klien socket.io Android akan berguna bagi saya, karena saya berencana untuk menggunakan nodejs / socket.io untuk antarmuka web. Tetapi klien asli cukup muda dan memiliki beberapa masalah terbuka. Dan di samping itu, saya memahami bahwa aplikasi android tidak memiliki manfaat menggunakan perpustakaan klien socket.io (selain tidak kompatibel dengan server socket.io 1.0), karena dukungan WebSocket dapat dijamin di sisi klien .

Persyaratan saya adalah sebagai berikut:

  • Kompatibilitas dengan Android API 9 dan lebih tinggi
  • Kemungkinan untuk terhubung melalui SSL
  • Simpan koneksi untuk waktu yang lama tanpa harus memegang wakelock permanen
  • Kompatibilitas dengan implementasi server nodejs websocket yang tersedia atau dengan socket.io

Adakah saran yang merupakan pustaka yang tepat untuk persyaratan ini?

sinar-x
sumber
Mungkin Suasana . Lihat Pertanyaan ini .
Basil Bourque
2
Saya bukan ahli WebSocket atau Atmosphere. Saya hanya tahu bahwa Atmosphere sudah usang, digunakan di banyak proyek untuk fitur Push termasuk dukungan WebSocket. Satu-satunya pengalaman saya tidak langsung, dalam membangun aplikasi web Vaadin . Vaadin menggunakan Atmosfer untuk kemampuan Push otomatisnya. Namun berhati-hatilah, WebSocket masih relatif baru dengan banyak perubahan definisi, spesifikasi, dan berbagai implementasi selama sejarah singkatnya. Jadi, harapkan "masalah" tidak peduli bagaimana Anda melakukannya.
Basil Bourque
2
FYI, Autobahn di luar sana dan mereka memiliki situs web yang mencolok. Tetapi tidak ada pemberitahuan bahwa "secure WebSockets tidak dilaksanakan" sampai Anda menghabiskan waktu untuk menginstal dan mencoba menjalankannya. Lanjut.
cloudsurfin
1
Saya tidak memiliki reputasi yang cukup untuk berkomentar jadi saya menulisnya sebagai jawaban karena saya telah melalui persyaratan yang sama yang Anda sebutkan dalam pertanyaan Anda dan okhttp membantu saya memenuhi semua persyaratan. Ini mendukung soket web sejak diperkenalkannya versi 3.5, Jadi ini merupakan keuntungan tambahan untuk menggunakan okHttp (panggilan layanan web + dukungan soket web). Inilah tautan untuk memulai. < medium.com/@ssaurel/… >
Kaleem Patel
7
Pertanyaan seperti ini jangan ditutup.
Martin Berger

Jawaban:

123

Beberapa catatan.

  • koush / AndroidAsync tidak melakukan jabat tangan penutup yang diperlukan oleh RFC 6455 . Lihat ini untuk detailnya.

  • Project Tyrus bekerja di Android, tetapi pastikan lisensi ( CDDL 1.1 dan GPL 2 dengan CPE ) dan ukurannya ( Mengurangi ukuran tabung klien WebSocket dengan ProGuard ) memenuhi persyaratan Anda. Perhatikan juga bahwa Tyrus dapat membuat pengecualian ketika ukuran teks besar (itu mungkin bug). Lihat ini untuk detailnya.

  • Jetty : Utas email 2 tahun yang lalu di milis pengguna jetty mengatakan, "Kami saat ini tidak memiliki klien WebSocket Jetty 9 yang kompatibel dengan Android. Ada rencana untuk mencoba untuk mendukung Klien WebSocket Jetty dari JDK 7 hingga JDK 5/6 untuk android gunakan, tapi ini prioritas yang lebih rendah daripada menyelesaikan implementasi JSR-356 Java WebSocket API kami (javax.websocket). " Dokumen Jetty tentang WebSocket Client API saat ini tidak menyebutkan apa pun tentang Android.

  • codebutler / android-websocket tidak melakukan jabat tangan penutup yang diperlukan oleh RFC 6455 dan dapat melempar pengecualian pada penutupan. Lihat ini .

  • Atmosphere / wasync menggunakan AsyncHttpClient / async-http-client sebagai implementasi WebSocket-nya. Jadi, lebih tepatnya, AsyncHttpClient / async-http-client harus disebutkan sebagai gantinya.

  • firebase / TubeSock tidak memverifikasi Sec-WebSocket-Accept. Ini merupakan pelanggaran terhadap RFC 6455 . TubeSock juga memiliki bug dalam membangun pesan teks. Anda akan menemukan bug cepat atau lambat jika Anda menggunakan multi-byte karakter UTF-8 untuk pesan teks. Lihat Edisi 3 di senang-im / Android-DDP untuk daftar panjang tentang masalah TubeSock.

Poin Pertimbangan

Poin pertimbangan dalam memilih implementasi klien WebSocket yang ditulis dalam Java:

  1. Kepatuhan . Tidak sedikit implementasi yang tidak mengimplementasikan handshake penutup yang dibutuhkan oleh RFC 6455 . (Apa yang terjadi jika jabat tangan penutup tidak dilaksanakan? Lihat ini .)
  2. Diperlukan versi Java . Java SE 5, 6, 7, 8 atau Java EE? Bekerja bahkan di Android?
  3. Ukuran . Beberapa implementasi memiliki banyak dependensi.
  4. dukungan wss .
  5. Dukungan proxy HTTP .
  6. wss melalui dukungan proxy HTTP . Lihat Gambar 2 di Bagaimana HTML5 Web Socket Berinteraksi dengan Server Proxy tentang apa yang harus dilakukan pustaka klien WebSocket untuk mendukung wss melalui proxy HTTP.
  7. Fleksibilitas pada konfigurasi SSL . SSLSocketFactorydan SSLContextharus dapat digunakan tanpa batasan yang tidak perlu.
  8. Tajuk HTTP khusus di jabat tangan pembuka , termasuk Otentikasi Dasar.
  9. Tajuk HTTP khusus dalam negosiasi proxy HTTP , termasuk otentikasi di server proxy.
  10. Mampu mengirim semua jenis bingkai (lanjutan, biner, teks, tutup, ping dan pong) atau tidak. Sebagian besar implementasi tidak menyediakan sarana bagi pengembang untuk mengirim frame terfragmentasi dan frame pong yang tidak diminta secara manual.
  11. Antarmuka pendengar untuk menerima berbagai acara WebSocket. Antarmuka yang buruk membuat pengembang frustrasi. Antarmuka yang kaya membantu pengembang menulis aplikasi yang tangguh.
  12. Dapat menanyakan status WebSocket atau tidak. RFC 6455 mendefinisikan status CONNECTING, OPEN, CLOSING dan CLOSED, tetapi beberapa implementasi mempertahankan transisi keadaan internal mereka dengan cara yang ditentukan.
  13. Dapat mengatur nilai batas waktu untuk koneksi soket . (Setara dengan argumen metode kedua )Socket.connect(SocketAddress endpoint, int timeout)
  14. Dapat mengakses soket mentah yang mendasarinya .
  15. API mudah digunakan intuitif atau tidak.
  16. Didokumentasikan dengan baik atau tidak.
  17. Dukungan RFC 7692 (Compression Extensions for WebSocket) (alias permessage-deflate).
  18. Dukungan pengalihan (3xx).
  19. Dukungan Otentikasi Intisari .

nv-websocket-client mencakup semua hal di atas kecuali dua yang terakhir. Selain itu, salah satu fitur kecil namun praktis adalah mengirim bingkai ping / pong secara berkala. Itu dapat dicapai hanya dengan memanggilsetPingInterval/setPongIntervalmetode (Lihat JavaDoc ).

Penafian: Takahiko Kawasaki adalah penulis nv-websocket-client.

Takahiko Kawasaki
sumber
1
Apakah perpustakaan nv-websocket-client masih dalam pengembangan? Saya menghadapi masalah pemutusan otomatis dengan TooTallNate / Java-WebSockets dengan kesalahan 1006 dan TIDAK ada alasan .. apakah nv-websocket ini juga menyelesaikannya?
Ankit Bansal
1
Adapun 1006, spesifikasi (RFC 6455) menyatakan bahwa kode TIDAK HARUS ditetapkan sebagai kode status dalam bingkai kontrol Tutup oleh titik akhir . Ini berarti bahwa kode tersebut dibuat di sisi klien. Anda dapat memperoleh informasi lebih lanjut tentang pemutusan melalui onDisconnectedmetode dan onErrormetode WebSocketListener . onErrorMetode memberi Anda sebuah WebSocketExceptioncontoh. Panggil getError()metodenya untuk melihat apa masalahnya.
Takahiko Kawasaki
7
Untuk wss, saya mencoba okhttp dan autobahn (juga menduga promosi diri dalam jawaban ini). Autobahn mudah, tetapi tidak memiliki SSL. OkHttp memiliki sedikit (nol) dokumentasi (konsolidasi) (Feb 2016). Saya membuang-buang waktu untuk membaca kode dan pengecualian mereka karena saya tidak tahu cara mengatasi masalah (seperti mengatur batas waktu ke 0, atau menutup pesan masuk) untuk mendapatkan contoh tulang kosong yang berfungsi. Membuang kedua (dan frustrasi saya), saya menemukan n (dengan menyegarkan) didokumentasikan dengan baik; itu bekerja tanpa keributan.
cloudsurfin
1
Adakah pemikiran tentang dukungan websockets Square / okhttp yang baru? medium.com/square-corner-blog/…
scorpiodawg
2
Saya tidak tahu detail tentang OkHttp. Maaf, saya sangat sibuk sebagai pendiri Authlete, Inc. (" Startup keamanan API Authlete mengumpulkan $ 1,2 juta dalam pendanaan awal ") Saya tidak dapat meluangkan waktu untuk melihat OkHttp dan memperbarui daftar poin pertimbangan. Mengenai perubahan sejak jawaban saya, lihat CHANGES.md . Harap dicatat nv-websocket-client hanyalah hobi saya sementara OkHttp tampaknya merupakan proyek besar yang memiliki 138 kontributor.
Takahiko Kawasaki
4

Beberapa pertimbangan lain:

Tyrus bekerja di Android. Namun, pustaka SSL yang digunakannya di Android 5.0 buggy dan gagal handshake SSL . Ini seharusnya diperbaiki di versi Android yang lebih baru, tetapi dengan cara Android tidak diperbarui pada banyak perangkat, ini mungkin menjadi masalah bagi Anda.

Bergantung pada bagaimana SSL diterapkan untuk implementasi websocket lain, ini juga bisa menjadi masalah.

AndroidAsync tidak memiliki masalah SSL ini. Itu memang memiliki masalah lain seperti tidak dapat mengatur batas waktu .

mattm
sumber
3

a) Tambahkan file ini dalam file gradle

compile 'com.github.nkzawa:socket.io-client:0.3.0'

b) Tambahkan baris ini di Aktivitas Aplikasi:

    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) Tambahkan fungsi ini ke aktivitas Anda, tempat Anda memanggil 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(() -> {


            });
        }
    };
Anil Singhania
sumber
Ini tidak mendukung protokol ws: //.
Girish Bhutiya