简体   繁体   English

在android中实现Socket.io的最佳方法

[英]Best way to implement Socket.io in android

I am planning to implement Socket.io in android by this library for a chat based application. 我计划在这个库中为基于聊天的应用程序在android中实现Socket.io。 As far as I understood the library seems to be pretty good. 据我所知,图书馆看起来很不错。 I want to know how to maintain a single socket connection throughout the app all the time? 我想知道如何在整个应用程序中始终保持单个套接字连接? Here I have listed out ways to achieve, in which I need the best and stable way. 在这里,我列出了实现的方法,其中我需要最好和最稳定的方式。

Three ways 三种方式

MainApplication Class extends Application MainApplication类扩展了Application

By this we have a good scope that the socket connection is maintained in the main thread ( or application's life cycle) and whenever the socket instance is needed from the activity we can get it easily. 通过这种方式,我们有一个很好的范围,即在主线程 (或应用程序的生命周期)中维护套接字连接,并且每当从活动中需要套接字实例时我们都可以轻松获得它。 But it's main thread which also the problem. 但它的主要线索也是问题所在。 It might block the main thread. 它可能会阻止主线程。

BoundService BoundService

By this way we can bind the service with the activities and we can simply use it. 通过这种方式,我们可以服务与活动绑定 ,我们可以简单地使用它。 Doing in separate thread is the way to achieve IO/Network calls. 在单独的线程中执行是实现IO /网络调用的方法。 But cross processing transfer is more expensive than directly accessing in same process. 但是,交叉处理转移比在同一过程中直接访问更昂贵。

Singleton 独生子

Maintaining connection in Singleton also makes sense. 在Singleton中维护连接也很有意义。 But we don't know when the instance is killed by process, because it doesn't work in activity life cycle. 但是我们不知道实例何时被进程杀死,因为它在活动生命周期中不起作用。

If I makes sense please help me out. 如果我有意义,请帮助我。 If not comment it out. 如果没有评论出来。

Edit 编辑

I have given the answer which is more suitable for me. 我已经给出了更适合我的答案。

First of all, the Application's onCreate() is irrelevant in your use case because you can't have a thread running in the background when it was first initiated in a non service code. 首先,应用程序的onCreate()与您的用例无关,因为在非服务代码中首次启动时,您无法在后台运行线程。

Also, I would recommend using Google Cloud Messaging instead of creating your own mechanism. 此外,我建议使用Google Cloud Messaging而不是创建自己的机制。 It would be best for the device's battery life and much less code for you to handle. 最好是设备的电池寿命和更少的代码供您处理。

If you do want to implement that chat completely on your own, Service is your only choice. 如果您确实希望完全自己实现该聊天,那么Service是您唯一的选择。 You can also combine it with a singleton, but I wouldn't recommend that approach. 你也可以将它与单身人士结合起来,但我不建议采用这种方法。 You can use broadcasts and BroadcastReceiver for communicating between your Service and Activity , I think it is easier than a Bound Service since bounding to the service is asynchronous and it creates a lot of mess compared to simple broadcasting. 您可以使用广播和BroadcastReceiver在您的ServiceActivity之间进行通信,我认为它比绑定服务更容易,因为绑定到服务是异步的,与简单广播相比,它会造成很多混乱。

Service for Maintaining socket connection 维护socket连接的服务

As per Ofek Ron mentioned Service with BroadcaseReceiver is a better idea than BoundService . 根据Ofek Ron提到的Service with BroadcaseReceiverBoundService 更好 Because its a tedious process to maintain communication. 因为它是一个保持沟通的繁琐过程。 And I also recommend pub/sub way of broadcasting, like Otto or EventBus (I myself suggest Otto by Square, which is clean and brilliant api). 而且我也推荐pub/sub广播方式,比如OttoEventBus (我自己建议Otto by Square,这是干净而精彩的api)。

Pros of OTTO 奥托的优点
1. Cleaner Api 1.清洁Api
2. You can subscribe and publish in/to any Activity , Fragment , Service class. 2.您可以在任何ActivityFragmentService类中订阅和发布。
3. Decoupling . 3. 解耦 (You have to couple as less as possible in your code). (您必须在代码中尽可能少地耦合)。

And one more point is use START_STICKY in the onStartCommand() to start service after it is getting destroyed. 还有一点是在onStartCommand()使用START_STICKY在销毁之后启动服务。 See this reference. 请参阅参考。

MainApplication to start the service MainApplication启动服务

It's best practice to start the service in the MainApplication that extends Application . 最佳实践是在扩展ApplicationMainApplication中启动该服务。 Because the application will be killed when there is a memory constraint or user forcefully closes the app from the stack. 因为当存在内存约束或用户强行从堆栈中关闭应用程序时,应用程序将被终止。 So onStartCommand() will not be called frequently like if we have implemented in Activity. 所以onStartCommand()不会被频繁调用,就像我们在Activity中实现一样。

Implementing online status 实现在线状态

You can implement online status simply by implementing Application.LifeCycleCallbacks in the MainApplication class, which has most of the life cycle callbacks of activity and will be notified in the callback. 您可以通过在MainApplication类中实现Application.LifeCycleCallbacks来实现在线状态,该类具有活动的大部分生命周期回调,并将在回调中得到通知。 By that you can implement Online status simply without any boiler plate codes. 通过,你可以实现Online状态根本没有任何锅炉板代码。 (If anyone need help here let me know). (如果有人需要帮助,请告诉我)。

Uploading or downloading images or files. 上传或下载图像或文件。

Best practice is to implement by IntentService because it's running in the a separate thread. 最佳实践是由IntentService实现,因为它在单独的线程中运行。 I promise which will give the best performance because it is handled by android itself, not like threads created by us. 我保证哪个会提供最佳性能,因为它由android本身处理,而不是像我们创建的线程。

You can combine first way and third way like: 你可以结合第一种方式和第三种方式:

Create Socket s in your Application and declare them as static . 在您的Application创建Socket并将它们声明为static So you can maintain and access them every where in you application. 因此,您可以在应用程序的每个位置维护和访问它们。 Don't forget to create separate Thread s to perform the network operations, you can use ThreadPool to manage those Thread . 不要忘记创建单独的Thread来执行网络操作,可以使用ThreadPool来管理那些Thread If you want to update your UI from those Thread you can use Handler and Message to communication with UI Thread 如果要从这些Thread更新UI,可以使用HandlerMessage与UI Thread进行通信

Before you create your own implementation of a socket.io client, you should give this library a chance: https://github.com/socketio/socket.io-client-java 在创建自己的socket.io客户端实现之前,您应该给这个库一个机会: https//github.com/socketio/socket.io-client-java

I use it in one of my projects to communicate with a node.js server which is working pretty fine. 我在我的一个项目中使用它与node.js服务器进行通信,该服务器工作得非常好。 Actually, all of your suggestions are correct and mostly depend on what you want to achieve. 实际上,你的所有建议都是正确的,主要取决于你想要达到的目标。 However, one context is always available: the application context. 但是,一个上下文始终可用:应用程序上下文。 Therefore you should keep a singleton instance in the Application class and get it by getApplicationContext() . 因此,您应该在Application类中保留一个单例实例,并通过getApplicationContext()获取它。

Online status of the user: here you should create a background service which is listening constantly for the users state. 用户的在线状态:在这里,您应该创建一个后台服务,该服务正在不断地监听用户状态。 As there are not many information, this should be okay and should not drain the battery too much. 由于信息不多,这应该没问题,不应该耗费太多电池。 Additionally you can send a flag if there are new information available and only if there is something new, you start another thread, which is receiving the new data. 此外,如果有可用的新信息,您可以发送标记,并且只有在有新内容的情况下,才会启动另一个接收新数据的线程。 This keeps the data low. 这样可以保持较低的数据。

Chat: the chat data is transfered only when the app is active. 聊天:聊天数据仅在应用处于活动状态时传输。 So, this should be done in an activity. 所以,这应该在一个活动中完成。

Both the service and the activity can access the singleton instance of the socket.io client from the application context. 服务和活动都可以从应用程序上下文访问socket.io客户端的单例实例。 As long as you do not process any complex data on the main thread everything is fine. 只要你不处理主线程上的任何复杂数据,一切都很好。 So, wrap your calls into separate thread and only start them when they are actually needed. 因此,将您的调用包装到单独的线程中,并仅在实际需要时启动它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM