ห้องสมุด WebSocket ใดที่จะใช้ในแอพ Android [ปิด]


131

ฉันต้องการเพิ่มบริการลงในแอพ Android ของฉันซึ่งทำงานอยู่เบื้องหลังโดยถือการเชื่อมต่อWebSocket (อาจใช้เวลาหลายชั่วโมงหรือหลายวัน) และส่งข้อมูลบางอย่างไปยังเซิร์ฟเวอร์เป็นประจำ

ตอนนี้ดูเหมือนจะมีห้องสมุด WebSocket จำนวนมากสำหรับ Java และฉันไม่แน่ใจว่าควรใช้อันไหน:

  • TooTallNate / Java-WebSocket คำอธิบายจาก GitHub: การใช้งานไคลเอนต์และเซิร์ฟเวอร์ของ WebSocket แบร์โบนที่เขียนด้วย Java 100% http://java-websocket.org/ - หนึ่งนี้มีการเชื่อมโยงในผลครั้งแรกของฉัน googling "หุ่นยนต์ WebSocket" อย่างไรก็ตามมีปัญหาที่เปิดอยู่เล็กน้อยโดยเฉพาะอย่างยิ่งเกี่ยวกับการเชื่อมต่อ SSL และดูเหมือนจะยังไม่ได้รับการบำรุงรักษาอย่างแข็งขันในขณะนี้

  • koush / AndroidAsync คำอธิบายจาก GitHub: ซ็อกเก็ตแบบอะซิงโครนัส http (ไคลเอนต์ + เซิร์ฟเวอร์), websocket และ socket.io ไลบรารี่สำหรับ Android อิงตาม nio ไม่ใช่เธรด - ปัญหาเปิดอีกมากมาย แต่ดูเหมือนว่าจะรักษา / ทำงาน activiley

  • โครงการ Tyrus คำอธิบายจากเว็บไซต์: JSR 356: Java API สำหรับ WebSocket - การดำเนินการอ้างอิง - นี้ทำโดย Oracle ไม่แน่ใจว่ามันใช้งานได้ใน Android หรือไม่

  • ข้อมูลลูกค้า Jetty WebSocket APIจากเว็บไซต์: Jetty ยังให้บริการห้องสมุดลูกค้า Jetty WebSocket เพื่อให้การเขียนพูดคุยกับเซิร์ฟเวอร์ WebSocket ง่ายขึ้น - อีกครั้ง: ไม่แน่ใจว่ามันใช้งานได้ใน Android

  • codebutler / หุ่นยนต์ WebSockets คำอธิบายจาก GitHub: เปลือย WebSockets ขั้นต่ำ (hybi13 / RFC) ไคลเอนต์สำหรับ Android - หนึ่งนี้จะใช้ใน schwiz / หุ่นยนต์ WebSocket-ตัวอย่างซึ่งเป็นคำตอบที่ได้รับการยอมรับสำหรับ 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 โมดูล ตามที่กล่าวไว้โดย scorpiodawg OkHttp มีการสนับสนุน websocket ในตัวตั้งแต่รุ่น 3.5

  • firebase / TubeSock คำอธิบายจาก GitHub: ไลบรารีไคลเอ็นต์ WebSocket ที่ใช้งานใน Java

  • Autobahn | Android ( GitHub ) คำอธิบายจากเว็บไซต์: Autobahn | Android เป็นห้องสมุดเครือข่ายโอเพ่นซอร์สสำหรับ Java / Android ที่สร้างขึ้นโดยโครงการ Autobahn ที่ใช้โปรโตคอล WebSocket และ Web Application Messaging Protocol (WAMP) สำหรับสร้าง Mobile WebSocket / WAMP ลูกค้า - cloudsurfin ชี้ให้เห็นว่าสิ่งนี้ไม่สนับสนุน wss

นอกจากนี้ยังมีไลบรารี่ดั้งเดิมของsocket.ioสำหรับ Android:

  • nkzawa / socket.io-client.java คำอธิบายจาก GitHub: ไลบรารีไคลเอ็นต์ Socket.IO แบบเต็มสำหรับ Java ซึ่งเข้ากันได้กับ Socket.IO v1.0 และใหม่กว่า

หากต้องการใช้ socket.io Android ไคลเอ็นต์จะเป็นประโยชน์สำหรับฉันเพราะฉันวางแผนที่จะใช้ nodejs / socket.io สำหรับส่วนหน้าของเว็บต่อไป แต่ลูกค้าในประเทศยังค่อนข้างใหม่และมีปัญหาเปิดหลายอย่าง และนอกจากนั้นฉันเข้าใจว่าแอพ android ไม่มีประโยชน์ใด ๆ ในการใช้ไลบรารีไคลเอ็นต์ socket.io (นอกเหนือจากการเข้ากันได้กับเซิร์ฟเวอร์ socket.io 1.0) เนื่องจากการสนับสนุน WebSocket สามารถมั่นใจได้ที่ฝั่งไคลเอ็นต์ .

ความต้องการของฉันมีดังนี้:

  • ความเข้ากันได้กับ Android API 9 และสูงกว่า
  • ความเป็นไปได้ในการเชื่อมต่อผ่าน SSL
  • คงการเชื่อมต่อเป็นเวลานานโดยไม่ต้องถือ wakelock ถาวร
  • ความเข้ากันได้กับการใช้งานเซิร์ฟเวอร์ nodejs websocket หรือกับ socket.io

ข้อเสนอแนะใดที่เป็นห้องสมุดที่เหมาะสมสำหรับข้อกำหนดเหล่านี้


บางทีบรรยากาศ ดูคำถามนี้
Basil Bourque

2
ฉันไม่มีความเชี่ยวชาญใน WebSocket หรือ Atmosphere ฉันรู้แค่ว่า Atmosphere นั้นใช้งานได้ดีในหลายโครงการสำหรับฟีเจอร์Pushรวมถึงการรองรับ WebSocket ประสบการณ์เดียวของฉันคือทางอ้อมในการสร้างVaadinเว็บแอป Vaadin ใช้ Atmosphere สำหรับความสามารถในการกดอัตโนมัติ แต่ระวัง WebSocket ยังค่อนข้างใหม่กับการเปลี่ยนแปลงหลายประการในการกำหนดรายละเอียดและการใช้งานต่างๆในช่วงประวัติย่อ ดังนั้นคาดว่า "ปัญหา" ไม่ว่าคุณจะไปที่ไหน
Basil Bourque

2
FYI, Autobahn อยู่ที่นั่นและพวกเขามีเว็บไซต์ที่ฉูดฉาด แต่ไม่มีการแจ้งเตือนว่า "ไม่ได้ติดตั้ง WebSockets ที่ปลอดภัย" จนกว่าคุณจะใช้เวลาในการติดตั้งและลองเปิดใช้งาน ต่อไป.
cloudsurfin

1
ฉันไม่มีชื่อเสียงพอที่จะแสดงความคิดเห็นดังนั้นฉันจึงเขียนมันเป็นคำตอบเพราะฉันผ่านข้อกำหนดเดียวกันกับที่คุณพูดถึงในคำถามของคุณและ okhttp ช่วยให้ฉันสามารถตอบสนองความต้องการทั้งหมดได้ รองรับซ็อกเก็ตเว็บตั้งแต่การเปิดตัวเวอร์ชัน 3.5 ดังนั้นจึงเป็นข้อได้เปรียบเพิ่มเติมในการใช้ okHttp (การบริการทางเว็บการโทร + การสนับสนุนซ็อกเก็ตเว็บ) นี่คือลิงค์สำหรับเริ่มต้นด้วย < medium.com/@ssaurel/ ...... >
Kaleem Patel

7
คำถามเช่นนี้ไม่ควรปิด
Martin Berger

คำตอบ:


123

บางบันทึก

  • koush / AndroidAsyncไม่ทำการจับมือปิดซึ่งRFC 6455ต้องการ ดูนี้สำหรับรายละเอียด

  • Project Tyrus ใช้งานได้บน Android แต่ต้องแน่ใจว่าสิทธิ์ใช้งาน ( CDDL 1.1 และ GPL 2 พร้อม CPE ) และขนาดของมัน ( ลดขนาดโถไคลเอนต์ WebSocket ไคลเอ็นต์ด้วย ProGuard ) โปรดทราบว่า Tyrus อาจมีข้อยกเว้นเมื่อขนาดตัวอักษรใหญ่ (อาจเป็นข้อผิดพลาด) ดูนี้สำหรับรายละเอียด

  • Jetty : เธรดอีเมล 2 ปีที่ผ่านมาในรายชื่อผู้รับจดหมาย Jetty ผู้ใช้บอกว่า"ขณะนี้เราไม่มีไคลเอนต์ Jetty 9 WebSocket ที่เข้ากันได้กับ Android มีแผนการที่จะพยายาม backport ไคลเอนต์ Jetty WebSocket จาก JDK 7 เป็น JDK 5/6 สำหรับ Android ใช้ แต่มันมีความสำคัญต่ำกว่าการทำให้การใช้งาน Java WebSocket API ของ JSR-356 ของเราเสร็จสิ้น (javax.websocket) " เอกสารปัจจุบันของ Jetty เกี่ยวกับ WebSocket Client API ไม่ได้พูดถึงสิ่งใดเกี่ยวกับ Android

  • codebutler / android-websocketไม่ทำการปิด handshakeซึ่งRFC 6455 ต้องการและอาจทำให้เกิดข้อยกเว้นเมื่อปิด ดูนี่สิ

  • Atmosphere / wasyncใช้AsyncHttpClient / async-http-clientเป็นการใช้งาน WebSocket ดังนั้นควรกล่าวถึง AsyncHttpClient / async-http-client แทน

  • Firebase / TubeSockSec-WebSocket-Acceptไม่ได้ตรวจสอบ ซึ่งเป็นการละเมิดกับRFC 6455 นอกจากนี้ TubeSock มีข้อบกพร่องในการสร้างข้อความ คุณจะพบข้อผิดพลาดไม่ช้าก็เร็วหากคุณใช้อักขระ UTF-8 หลายไบต์สำหรับข้อความตัวอักษร ดูฉบับที่ 3ในdelight-im / Android-DDPสำหรับรายการสั้น ๆ เกี่ยวกับปัญหา TubeSock

จุดพิจารณา

จุดพิจารณาในการเลือกใช้งานไคลเอนต์ WebSocket ที่เขียนใน Java:

  1. การปฏิบัติตาม ไม่ได้เป็นจำนวนเล็ก ๆ ของการใช้งานที่ไม่ได้ดำเนินการจับมือปิดที่จำเป็นโดยRFC 6455 (จะเกิดอะไรขึ้นหากไม่มีการใช้ handshake ในการปิดดูที่นี่ )
  2. รุ่นต้องใช้ Java Java SE 5, 6, 7, 8 หรือ Java EE? ทำงานได้แม้ใน Android?
  3. ขนาด การใช้งานบางอย่างมีการอ้างอิงจำนวนมาก
  4. การสนับสนุนwss
  5. การสนับสนุนพร็อกซี HTTP
  6. wss ผ่านการสนับสนุนพร็อกซี HTTP ดูรูปที่ 2 วิธีที่เว็บซ็อกเก็ต HTML5 โต้ตอบกับพร็อกซีเซิร์ฟเวอร์เกี่ยวกับสิ่งที่ไลบรารีไคลเอ็นต์ WebSocket ต้องทำเพื่อสนับสนุน wss ผ่านพร็อกซี HTTP
  7. ความยืดหยุ่นในการกำหนดค่า SSL SSLSocketFactoryและSSLContextควรสามารถใช้งานได้โดยไม่มีข้อ จำกัด ที่ไม่จำเป็น
  8. ส่วนหัว HTTP ที่กำหนดเองในการจับมือเปิดรวมถึงการตรวจสอบเบื้องต้น
  9. ส่วนหัว HTTP ที่กำหนดเองในการเจรจาพร็อกซี HTTPรวมถึงการตรวจสอบที่พร็อกซีเซิร์ฟเวอร์
  10. ความสามารถในการส่งเฟรมทุกประเภท (ความต่อเนื่อง, ไบนารี, ข้อความ, ปิด, ping และ pong) หรือไม่ การใช้งานส่วนใหญ่ไม่ได้ให้วิธีในการส่งเฟรมแยกส่วนและเฟรมพงษ์ที่ไม่พึงประสงค์ แก่ผู้พัฒนาด้วยตนเอง
  11. ส่วนต่อประสานฟังเพื่อรับเหตุการณ์ WebSocket ต่างๆ ส่วนต่อประสานที่ไม่ดีทำให้นักพัฒนาผิดหวัง อินเทอร์เฟซที่หลากหลายช่วยให้นักพัฒนาเขียนแอปพลิเคชันที่มีประสิทธิภาพ
  12. สามารถสอบถามสถานะ WebSocketได้หรือไม่ RFC 6455กำหนดสถานะ CONNECTING, OPEN, CLOSING และ CLOSED แต่การใช้งานเพียงไม่กี่แห่งนั้นยังคงรักษาสถานะการเปลี่ยนแปลงภายในของตนไว้ในแนวทางที่กำหนดไว้
  13. สามารถตั้งค่าการหมดเวลาสำหรับการเชื่อมต่อซ็อกเก็ต (เทียบเท่ากับอาร์กิวเมนต์ที่สองของวิธีการ)Socket.connect(SocketAddress endpoint, int timeout)
  14. สามารถเข้าถึงซ็อกเก็ตดิบพื้นฐาน
  15. API ที่ใช้งานง่ายใช้งานง่ายหรือไม่
  16. มีเอกสารครบถ้วนหรือไม่
  17. การสนับสนุน RFC 7692 (ส่วนขยายการบีบอัดสำหรับ WebSocket) (aka permessage-deflate)
  18. รองรับการเปลี่ยนเส้นทาง (3xx)
  19. สนับสนุนการรับรองความถูกต้อง Digest

nv-websocket-clientครอบคลุมทั้งหมดข้างต้นยกเว้นสองอันสุดท้าย นอกจากนี้หนึ่งในคุณสมบัติที่มีขนาดเล็ก แต่สะดวกสบายก็คือการส่งเฟรมปิง / ปิงปองเป็นระยะ สามารถทำได้โดยการโทรsetPingInterval/setPongIntervalวิธี (ดู JavaDoc )

คำเตือน: ทาคาฮิโกะคาวาซากิเป็นผู้เขียนของ nv-websocket- ลูกค้า


1
nv-websocket-client ยังคงอยู่ระหว่างการพัฒนา? ฉันประสบปัญหาการตัดการเชื่อมต่ออัตโนมัติกับ TooTallNate / Java-WebSockets ที่มีข้อผิดพลาด 1006 และไม่มีเหตุผล .. nv-websocket นี้ยังแก้ไขได้หรือไม่
Ankit Bansal

1
สำหรับ 1006 สเปค (RFC 6455) ระบุว่ารหัสจะต้องไม่ถูกกำหนดให้เป็นรหัสสถานะในกรอบการควบคุมโดยปิดปลายทาง ซึ่งหมายความว่ารหัสถูกสร้างขึ้นบนฝั่งไคลเอ็นต์ คุณจะได้รับข้อมูลเพิ่มเติมเกี่ยวกับการเชื่อมต่อผ่านonDisconnectedวิธีการและonErrorวิธีการของการWebSocketListener onErrorวิธีการให้WebSocketExceptionตัวอย่าง เรียกgetError()วิธีการเพื่อดูว่าปัญหาคืออะไร
Takahiko Kawasaki

7
สำหรับ wss ฉันลองใช้ okhttp และ autobahn (ก็สงสัยว่าจะโปรโมตตัวเองในคำตอบนี้) Autobahn นั้นง่าย แต่ไม่มี SSL OkHttp มีเอกสารน้อยถึงศูนย์ (รวมแล้ว) (ก.พ. 2559) ฉันเสียเวลามากในการอ่านรหัสและข้อยกเว้นของพวกเขาเพราะฉันไม่ได้เป็นการส่วนตัวในการแก้ไขปัญหา (เช่นตั้งค่าการหมดเวลาเป็น 0 หรือปิดข้อความขาเข้า) เพื่อให้ตัวอย่างกระดูกเปลือยทำงาน ทิ้งทั้งสอง (และความหงุดหงิดของฉัน) ฉันพบ nv (สดชื่น) เอกสารดี; มันทำงานได้โดยไม่ต้องยุ่งยาก
cloudsurfin

1
มีความคิดเห็นเกี่ยวกับ websockets ใหม่ของ Square / okhttp ไหม? medium.com/square-corner-blog/…
scorpiodawg

2
ฉันไม่ทราบรายละเอียดเกี่ยวกับ OkHttp ฉันขอโทษฉันยุ่งมากในฐานะผู้ก่อตั้งAuthlete, Inc. ("การรักษาความปลอดภัย API เริ่มต้น Authlete ระดมเงิน $ 1.2m ในการระดมทุนเมล็ดพันธุ์ ") ฉันไม่สามารถสละเวลาเพื่อค้นหา OkHttp และอัปเดตรายการจุดพิจารณา เกี่ยวกับการเปลี่ยนแปลงตั้งแต่คำตอบของฉันดูCHANGES.md โปรดทราบว่า nv-websocket-client เป็นเพียงงานอดิเรกของฉันในขณะที่ OkHttp ดูเหมือนจะเป็นโครงการขนาดใหญ่ที่มีผู้ร่วมให้ข้อมูลถึง 138 คน
Takahiko Kawasaki

4

ข้อควรพิจารณาอื่น ๆ :

Tyrus ใช้งานได้บน 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) เพิ่มบรรทัดเหล่านี้ในแอปพลิเคชันกิจกรรม:

    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) เพิ่มฟังก์ชั่นนี้ในกิจกรรมที่คุณเรียกว่า 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(() -> {


            });
        }
    };

สิ่งนี้ไม่รองรับโปรโตคอล ws: //
Girish Bhutiya
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.