Android 套接字连接和轮询。就电池寿命而言,哪个是更好的解决方案?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11789407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:52:16  来源:igfitidea点击:

Socket connections and Polling. Which is a better solution in terms of battery life?

androidsocketstcppollingbattery

提问by shadrx

So... I'm making an application for Android. The application needs to send and receive realtime chat data (needs to be a socket) but it also needs to send commands (which don't as the client knows when it is sending something).

所以......我正在为Android制作一个应用程序。应用程序需要发送和接收实时聊天数据(需要是一个套接字),但它也需要发送命令(客户端在发送某些东西时不知道)。

I need to know what is a better solution in terms of saving the user's battery.

我需要知道在节省用户电池方面什么是更好的解决方案。

a)Opening and Closing the connection every time a command is sent, if the chat tab is opened then keep the connection constant.

a)每次发送命令时打开和关闭连接,如果打开聊天选项卡,则保持连接不变。

b)Keep the connection constant all the time.

b)始终保持连接不变。

I've taken a look around the internet but have gotten mixed answers, some say keeping a persistent connection is bad for battery life and others say that it isn't (Example: "Are you asking if holding a TCP connection open will drain battery-life? Maybe I am WAY off here but, holding a connection open shouldn't waste battery life... If you think it will I would love to know where you got that information. It sounds SO strange to me.")

我浏览了互联网,但得到的答案不一,有人说保持持久连接不利于电池寿命,而另一些人说它不是(例如:“您是否询问保持 TCP 连接打开是否会耗尽电池电量? -life?也许我已经离开这里了,但是,保持连接打开不应该浪费电池寿命......如果你认为它会我很想知道你从哪里得到这些信息。这对我来说听起来很奇怪。”

Or if there is another solution that would be better. I don't think that Google's C2DM would be very useful at all in this situation either.

或者如果有另一种更好的解决方案。我也不认为 Google 的 C2DM 在这种情况下会很有用。

Basically, what drains the battery more: having a persistent connection, or opening and closing the connection unless the chat tab is open?

基本上,什么更耗电:保持持续连接,或者除非打开聊天选项卡,否则打开和关闭连接?

Thanks!

谢谢!

回答by Jeremy Friesner

Keeping an idle TCP socket connection open (with no data being sent or received) will not (or at least, should not) consume any more battery than having it closed. That is because an idle TCP connection uses no bandwidth or CPU cycles(*).

保持空闲的 TCP 套接字连接打开(没有发送或接收数据)不会(或至少不应该)比关闭它消耗更多的电池。那是因为空闲的 TCP 连接不使用带宽或 CPU 周期(*)。

That said, keeping a TCP connection open for extended periods may not be a good option for a mobile device, because TCP connections don't interact well with computers that go to sleep. The problem scenario would be this: your Android user puts his Android device to sleep while your app is running, and then the remote user's program (or whatever is at the other end of the TCP connection) sends some data over the TCP stream. The remote user's program never gets any ACKs back from the Android device, because of course the Android device is asleep, so the remote device's TCP stack assumes that the TCP packets it sent must have been lost, and it responds by increasing its timeout period, decreasing its TCP window size (aka number-of-TCP-packets-allowed-in-flight-at-once), and resending the TCP packets. But the Android device is still asleep, and thus the same thing happens again. The upshot is that a few minutes later, the remote end of the TCP connection has slowed down to the point where even if the Android device was to wake up, the TCP connection will likely be too slow to be usable -- at which point your program will need to close the bogged-down TCP connection and start up a fresh one anyway, so why bother trying to keep it open?

也就是说,长时间保持 TCP 连接打开对于移动设备来说可能不是一个好的选择,因为 TCP 连接不能与进入睡眠状态的计算机很好地交互。问题场景是这样的:当您的应用程序运行时,您的 Android 用户将他的 Android 设备置于睡眠状态,然后远程用户的程序(或 TCP 连接另一端的任何程序)通过 TCP 流发送一些数据。远程用户的程序永远不会从 Android 设备收到任何 ACK,因为 Android 设备当然处于睡眠状态,因此远程设备的 TCP 堆栈假定它发送的 TCP 数据包肯定已经丢失,并通过增加其超时时间来响应,减少它的 TCP 窗口大小(又名 TCP 数据包数量),并重新发送 TCP 数据包。但是Android设备仍然处于睡眠状态,因此同样的事情再次发生。结果是几分钟后,TCP 连接的远程端的速度减慢到即使 Android 设备唤醒,TCP 连接也可能太慢而无法使用——此时您的程序将需要关闭陷入困境的 TCP 连接并无论如何都要启动一个新的连接,那么为什么还要尝试保持打开状态呢?

So my recommendation would be to go with option (a), with the stipulation that you close the TCP connection as part of your device-is-going-to-sleep-now routine.

所以我的建议是使用选项 (a),并规定您关闭 TCP 连接作为设备即将进入睡眠程序的一部分。

One possible caveat would be if Android has a feature where keeping a TCP connection open causes the WiFi or cell-network hardware to remain powered up in a situation where it could otherwise be put to sleep -- if that is the case, then the Android device would pay a battery cost for powering the antenna, which it wouldn't otherwise have had to pay. I'm not aware of any Android logic like that, but I've only used Android a little so that might just be ignorance on my part. It might be worth testing for, at least.

一个可能的警告是,如果 Android 具有保持 TCP 连接打开的功能,会导致 WiFi 或蜂窝网络硬件在本来可以进入睡眠状态的情况下保持通电状态——如果是这种情况,那么 Android设备将支付电池成本来为天线供电,否则它就不必支付。我不知道任何类似的 Android 逻辑,但我只使用了一点 Android,所以这可能只是我的无知。至少,它可能值得测试。

(*) Well, technically TCP does send a "keepalive" packet every so often while a TCP connection is open, and that does use some CPU cycles and antenna power... but the default interval for sending keepalive packets on Android is two hours, so I doubt the power used for that would be noticeable.

(*) 好吧,从技术上讲,TCP 确实会在 TCP 连接打开时每隔一段时间发送一个“keepalive”数据包,这确实会使用一些 CPU 周期和天线功率……但是在 Android 上发送 keepalive 数据包的默认间隔是两个小时,所以我怀疑用于那个的力量会引人注目。

回答by JeffS

In order to actually keep a connection open, you'd likely have to send heartbeat signals back and forth, as any stateful routers between the android device and your servers would forget about the connection after a relatively short time out.

为了实际保持连接打开,您可能必须来回发送心跳信号,因为 android 设备和您的服务器之间的任何有状态路由器都会在相对较短的超时后忘记连接。

Which is better all depends on how long you think you'll go without needing to connect to the server. If you're connecting about once every 30 seconds or so most of the time anyways, definitely keep the connection open, but if not, you might be better off closing it.

哪个更好取决于您认为不需要连接到服务器的时间。如果您在大多数情况下每 30 秒左右连接一次,一定要保持连接打开,但如果不是,您最好关闭它。

回答by user2485984

The battery is very much related to radio state transitions on 3G from DCH/FACH/IDLE. If you want to have an app which is energy efficient you should send as much of data as possible on limited time interval irrelevant of a persistent connection or not...

电池与 3G 上从 DCH/FACH/IDLE 的无线电状态转换密切相关。如果您想拥有一个节能的应用程序,您应该在与持久连接无关的有限时间间隔内发送尽可能多的数据......