Thư viện WebSocket nào sẽ được sử dụng trong ứng dụng Android? [đóng cửa]


131

Tôi muốn thêm Dịch vụ vào ứng dụng Android chạy trên nền có kết nối WebSocket (có thể trong vài giờ hoặc thậm chí vài ngày) và thường xuyên gửi một số dữ liệu đến máy chủ.

Bây giờ dường như có một loạt các thư viện WebSocket cho Java và tôi không chắc nên sử dụng thư viện nào:

Ngoài ra, có một thư viện máy khách socket.io dành cho Android:

  • nkzawa / socket.io-client.java Mô tả từ GitHub: Thư viện máy khách Socket.IO đầy đủ tính năng cho Java, tương thích với Socket.IO v1.0 trở lên.

Để sử dụng máy khách Android socket.io sẽ thuận tiện cho tôi, vì tôi dự định sử dụng nodejs / socket.io cho giao diện web bằng mọi cách. Nhưng khách hàng bản địa còn khá trẻ và có một số vấn đề mở. Và ngoài ra, tôi hiểu rằng một ứng dụng Android không có bất kỳ lợi ích nào khi sử dụng thư viện máy khách socket.io (ngoài việc tương thích với máy chủ socket.io 1.0), bởi vì hỗ trợ WebSocket có thể được đảm bảo ở phía máy khách .

Yêu cầu của tôi như sau:

  • Khả năng tương thích với API Android 9 trở lên
  • Khả năng kết nối qua SSL
  • Giữ kết nối trong một thời gian dài mà không cần phải giữ một wakelock vĩnh viễn
  • Khả năng tương thích với triển khai máy chủ websocket của nodejs hoặc với socket.io

Bất kỳ đề xuất nào là một thư viện phù hợp cho các yêu cầu này?



2
Tôi không phải là chuyên gia về WebSocket cũng như Khí quyển. Tôi chỉ biết rằng Khí quyển đã mòn, được sử dụng trong nhiều dự án cho các tính năng Push bao gồm hỗ trợ WebSocket. Kinh nghiệm duy nhất của tôi là gián tiếp, trong việc xây dựng các ứng dụng web Vaadin . Vaadin sử dụng Khí quyển cho khả năng Đẩy tự động. Nhưng hãy cẩn thận, WebSocket vẫn còn tương đối mới với nhiều thay đổi về định nghĩa, thông số kỹ thuật và các triển khai khác nhau trong lịch sử ngắn gọn của nó. Vì vậy, mong đợi "vấn đề" cho dù bạn đi như thế nào.
Basil Bourque

2
FYI, Autobahn ở ngoài đó và họ có một trang web hào nhoáng. Nhưng không có thông báo rằng "WebSockets an toàn không được triển khai" cho đến khi bạn dành thời gian để cài đặt và thử chạy nó. Kế tiếp.
cloudurfin

1
Tôi không có đủ danh tiếng để bình luận vì vậy tôi viết nó như một câu trả lời vì tôi đã trải qua các yêu cầu giống như bạn đã đề cập trong câu hỏi của bạn và okhttp đã giúp tôi đáp ứng tất cả các yêu cầu. Nó hỗ trợ các socket web kể từ khi giới thiệu phiên bản 3.5, do đó, một lợi thế bổ sung để sử dụng okHttp (hỗ trợ cuộc gọi dịch vụ web + hỗ trợ web socket). Đây là liên kết để bắt đầu. < Medium.com/@ssaurel/ Kẻ >
Kaleem Patel

7
Những câu hỏi như thế này không nên được đóng lại.
Martin Berger

Câu trả lời:


123

Một số lưu ý.

  • koush / AndroidAsync không thực hiện bắt tay đóngRFC 6455 yêu cầu . Xem điều này để biết chi tiết.

  • Project Tyrus hoạt động trên Android, nhưng đảm bảo rằng giấy phép của nó ( CDDL 1.1 và GPL 2 với CPE ) và kích thước của nó ( Giảm kích thước tệp ứng dụng khách WebSocket bằng ProGuard ) đáp ứng yêu cầu của bạn. Cũng lưu ý rằng Tyrus có thể đưa ra một ngoại lệ khi kích thước văn bản lớn (có thể là lỗi). Xem điều này để biết chi tiết.

  • Cầu tàu : Một chuỗi email 2 năm trước trong danh sách gửi thư của người dùng jetty cho biết "Chúng tôi hiện không có ứng dụng khách Jetty 9 WebSocket tương thích với Android. Có kế hoạch thử backport Client Jetty WebSocket từ JDK 7 sang JDK 5/6 cho Android sử dụng, nhưng mức độ ưu tiên thấp hơn so với việc hoàn thành việc triển khai API WebSocket của Java (javax.websocket). " Tài liệu hiện tại của Jetty về API khách hàng WebSocket của nó không đề cập bất cứ điều gì về Android.

  • codebutler / android-websocket không thực hiện bắt tay đóngRFC 6455 yêu cầu và có thể ném ngoại lệ vào gần. Xem này .

  • At Khí quyển / wasync sử dụng AsyncHttpClient / async-http-client làm triển khai WebSocket của nó. Vì vậy, thay vào đó, AsyncHttpClient / async-http-client nên được đề cập thay thế.

  • firebase / TubeSock không xác minh Sec-WebSocket-Accept. Đây là một vi phạm đối với RFC 6455 . Ngoài ra, TubeSock có một lỗi trong việc xây dựng một tin nhắn văn bản. Bạn sẽ gặp lỗi sớm hay muộn nếu bạn sử dụng các ký tự UTF-8 nhiều byte cho tin nhắn văn bản. Xem Vấn đề 3 trong thỏa thích-im / Android-DDP để biết danh sách dài về các sự cố của TubeSock.

Điểm cân nhắc

Điểm cân nhắc trong việc lựa chọn triển khai ứng dụng khách WebSocket được viết bằng Java:

  1. Tuân thủ . Không ít số lần triển khai không thực hiện bắt tay đóng theo yêu cầu của RFC 6455 . (Điều gì xảy ra nếu bắt tay đóng không được thực hiện? Xem phần này .)
  2. Phiên bản Java bắt buộc . Java SE 5, 6, 7, 8 hoặc Java EE? Hoạt động ngay cả trên Android?
  3. Kích thước . Một số thực hiện có nhiều phụ thuộc.
  4. hỗ trợ wss .
  5. Hỗ trợ proxy HTTP .
  6. wss qua hỗ trợ proxy HTTP . Xem Hình 2 trong Cách các Ổ cắm Web HTML5 tương tác với Máy chủ proxy về những gì thư viện máy khách WebSocket phải làm để hỗ trợ wss qua HTTP proxy.
  7. Linh hoạt về cấu hình SSL . SSLSocketFactorySSLContextcó thể được sử dụng mà không có những hạn chế không cần thiết.
  8. Tiêu đề HTTP tùy chỉnh trong bắt tay mở , bao gồm Xác thực cơ bản.
  9. Tiêu đề HTTP tùy chỉnh trong đàm phán proxy HTTP , bao gồm xác thực tại máy chủ proxy.
  10. Có khả năng gửi tất cả các loại khung (tiếp tục, nhị phân, văn bản, đóng, ping và pong) hoặc không. Hầu hết các triển khai không cung cấp cho các nhà phát triển phương tiện để gửi các khung phân mảnhkhung pong không được yêu cầu bằng tay.
  11. Giao diện Listener để nhận các sự kiện WebSocket khác nhau. Một giao diện kém khiến các nhà phát triển thất vọng. Một giao diện phong phú giúp các nhà phát triển viết các ứng dụng mạnh mẽ.
  12. Có thể hỏi nhà nước WebSocket hay không. RFC 6455 định nghĩa các trạng thái KẾT NỐI, MỞ, ĐÓNG và ĐÓNG, nhưng một số triển khai duy trì chuyển đổi trạng thái bên trong của chúng theo cách được xác định.
  13. Có thể đặt giá trị thời gian chờ cho kết nối ổ cắm . (Tương đương với đối số thứ hai của phương thức)Socket.connect(SocketAddress endpoint, int timeout)
  14. Có thể truy cập vào ổ cắm thô bên dưới .
  15. API trực quan dễ sử dụng hay không.
  16. Tài liệu tốt hay không.
  17. Hỗ trợ RFC 7692 (Tiện ích mở rộng nén cho WebSocket) (còn gọi là permessage-deflate).
  18. Hỗ trợ chuyển hướng (3xx).
  19. Hỗ trợ xác thực tiêu hóa .

nv-websocket-client bao gồm tất cả các mục trên trừ hai phần cuối. Ngoài ra, một trong những tính năng nhỏ nhưng tiện lợi của nó là gửi khung ping / pong theo định kỳ. Nó có thể đạt được chỉ bằng cách gọisetPingInterval/setPongIntervalphương thức (Xem JavaDoc ).

Tuyên bố miễn trừ trách nhiệm: Takahiko Kawasaki là tác giả của nv-websocket-client.


1
thư viện nv-websocket-client vẫn đang được phát triển? Tôi gặp phải sự cố ngắt kết nối tự động với TooTallNate / Java-WebSockets với lỗi 1006 và KHÔNG có lý do .. nv-websocket này cũng giải quyết nó?
Ankit Bansal

1
Đối với 1006, thông số kỹ thuật (RFC 6455) nói rằng mã KHÔNG PHẢI được đặt làm mã trạng thái trong khung điều khiển Đóng theo điểm cuối . Điều này có nghĩa là mã được tạo ở phía máy khách. Bạn có thể nhận thêm thông tin về việc ngắt kết nối thông qua onDisconnectedphương thức và onErrorphương pháp của WebSocketListener . onErrorphương thức cung cấp cho bạn một WebSocketExceptionví dụ. Gọi getError()phương thức của nó để xem vấn đề là gì.
Takahiko Kawasaki

7
Đối với wss, tôi đã thử okhttp và autobahn (cũng nghi ngờ về việc tự quảng cáo trong câu trả lời này). Autobahn rất dễ, nhưng không có SSL. OkHttp có ít tài liệu (không hợp nhất) (tháng 2 năm 2016). Tôi đã lãng phí rất nhiều thời gian để đọc mã của họ và các trường hợp ngoại lệ của họ vì tôi không biết cách giải quyết (như đặt thời gian chờ là 0 hoặc đóng tin nhắn đến) để làm cho một ví dụ xương trần hoạt động. Từ bỏ hai thứ đó (và sự thất vọng của tôi), tôi thấy nv (mới mẻ) được ghi chép lại; nó làm việc mà không phiền phức
cloudurfin

1
Bạn có suy nghĩ gì về hỗ trợ websockets mới của Square / okhttp không? Medium.com/sapes-corner-blog/ từ
scorpiodawg

2
Tôi không biết chi tiết về OkHttp. Tôi xin lỗi, tôi rất bận rộn khi là người sáng lập Authlete, Inc. (" Khởi động bảo mật API Authlete tăng 1,2 triệu đô la tài trợ hạt giống ") Tôi không thể dành thời gian để xem xét OkHttp và cập nhật danh sách các điểm xem xét. Về những thay đổi kể từ câu trả lời của tôi, xem CHANGES.md . Xin lưu ý nv-websocket-client chỉ là sở thích của tôi trong khi OkHttp dường như là một dự án lớn có 138 người đóng góp.
Takahiko Kawasaki

4

Một số cân nhắc khác:

Tyrus hoạt động trên Android. Tuy nhiên, các thư viện SSL mà nó sử dụng trong Android 5.0 bị lỗi và bắt tay SSL không thành công . Điều này được cho là đã được sửa trong các phiên bản Android mới hơn, nhưng với cách Android không được cập nhật trên nhiều thiết bị, đây có thể là một vấn đề đối với bạn.

Tùy thuộc vào cách SSL được triển khai cho các triển khai websocket khác, đây cũng có thể là một vấn đề.

AndroidAsync không có vấn đề SSL này. Nó có các vấn đề khác như không thể đặt thời gian chờ .


3

a) Thêm tệp này trong tệp gradle

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

b) Thêm các dòng này trong Hoạt động ứng dụng:

    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) Thêm chức năng này vào hoạt động của bạn, nơi bạn gọi là 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(() -> {


            });
        }
    };

Điều này không hỗ trợ giao thức ws: //.
Girish Bhutiya
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.