我正在 iOS 和 Android 中构建本机移动应用程序。这些应用程序需要从服务器进行“实时”更新,就像任何其他基于网络的应用程序一样(Facebook、Twitter、Words with Friends 等社交游戏等),
我认为为此使用 HTTP 长轮询在某种意义上是过度杀戮长轮询可能会损害电池寿命,尤其是在进行大量 TCP 设置/拆卸时。让移动应用程序使用持久 TCP 套接字建立与服务器的连接,并向服务器发送 RPC 样式命令以进行所有 Web 服务通信可能是有意义的。当然,这需要服务器能够处理长期存在的 TCP 连接,并且在理解通过 TCP 管道传递的数据后能够与 Web 服务进行通信。我正在考虑使用 JSON 或 XML 以纯文本形式传递数据。
也许基于 Erlang 的 RPC 服务器非常适合这样的基于网络的应用程序。它将允许移动应用程序通过一个连接从服务器发送和接收数据,而无需像 iOS 上的 NSURLConnection 之类的单个 HTTP 请求那样进行多次设置/拆卸。由于不涉及任何 Web 浏览器,因此我们不需要在移动客户端级别处理 HTTP 的细微差别。许多“COMET”和长轮询/流媒体服务器都是根据 HTTP 构建的。我认为仅使用 TCP 上的纯文本协议就足够了,将使客户端响应更快,允许从服务器接收更新,并比传统的长轮询和流模型保持电池寿命。
目前有人使用他们的原生 iOS 或 Android 应用程序执行此操作吗?您是否编写了自己的服务器,或者是否有一些开源的东西可供我今天开始使用,而不是重新发明轮子?为什么只使用基于 TCP 的 RPC 服务比使用 HTTP 更糟糕?
我还研究了 HTTP 管道,但在客户端上实现它时,看起来并不值得这么麻烦。另外,我不确定它是否允许在客户端<->服务器通信通道中进行双向通信。
任何见解将不胜感激。
I'm building native mobile applications in both iOS and Android. These apps require "realtime" updates from and to the server, same as any other network-based application does (Facebook, Twitter, social games like Words with Friends, etc)
I think using HTTP long polling for this is over kill in the sense that long polling can be detrimental to battery life, especially with a lot of TCP setup/teardown. It might make sense to have the mobile applications use persistent TCP sockets to establish a connection to the server, and send RPC style commands to the server for all web service communication. This ofcourse, would require a server to handle the long-lived TCP connection and be able to speak to a web service once it makes sense of the data passed down the TCP pipe. I'm thinking of passing data in plain text using JSON or XML.
Perhaps an Erlang based RPC server would do well for a network based application like this. It would allow for the mobile apps to send and receive data from the server all over one connection without multiple setup/teardown that individual HTTP requests would do using something like NSURLConnection on iOS. Since no web browser isn't involved, we don't need to deal with the nuances of HTTP at the mobile client level. A lot of these "COMET" and long-polling/streaming servers are built with HTTP in mind. I'm thinking just using a plain-text protocol over TCP is good enough, will make the client more responsive, allow for receiving of updates from the server, and preserve battery life over the traditional long polling and streaming models.
Does anyone currently do this with their native iOS or Android app? Did you write your own server or is there something open sourced out there that I can begin working with today instead of reinventing the wheel? Is there any reason why using just a TCP based RPC service is a worse decision than using HTTP?
I also looked into HTTP pipelining, but it doesn't look to be worth the trouble when it comes to implementing it on the clients. Also, I'm not sure if it would allow for bi-directional communication in the client<->server communication channel.
Any insight would be greatly appreciated.
发布评论
评论(6)
这完全取决于您发送的数据 - 数据的大小、及时性的重要性、更新的频率等。
如果您正在寻找相当懒惰的更新和详细的数据(例如 JSON),那么请使用 HTTP 彗星模式,如下所示正如其他答案所强调的那样,您会发现导航标准网络设备要容易得多。例如,如果您位于公司防火墙/代理后面,则 http 将是一个更安全的选择。
然而,如果您正在以小数据量做快速的事情,那么请使用自制的东西并利用 TCP 连接。这更切题,您会发现实际性能要好得多。简单的数据结构并使用快速运算符根据需要对数据进行切片。
正如其他海报所指出的,电池使用是一个大问题。如果你不小心的话,你的口袋里就会被烧出一个洞,从而吃掉一块电池。将续航 2 天的电池变成续航 6 小时的电池非常容易。
最后,如果您对时间敏感,请不要相信网络。如果您不这样做,那么通过 HTTP 进行长轮询就可以了。但如果您正在寻找高性能消息传递,那么请敏锐地意识到移动网络不是端到端 TCP 连接。您的请求在行程时间和延迟方面会有所不同。
回到您想用该应用程序做什么。当您正在为 iOS(显然是本机指定)和 Andriod 进行构建时,我将利用 Apple Push Services 及其通知框架。构建后端服务与之通信,并为非 Apple 设备提供接口(即 http 或 tcp 级别侦听器)。这样一来,您的应用程序就有一个平台和多个“网关”。如果您愿意,您也可以通过 RIM 的推送服务进行操作。
It all depends on what data you are sending - the size of it, the criticality of timeliness, frequency of update etc.
If you are looking for a reasonably lazy update and verbose data (JSON say) then go with a HTTP comet pattern, as you will find it much easier to navigate standard network gear as other answers have highlighted. If you are behind a corporate firewall/proxy for example, http will be a much safer bet.
However, if you are doing fast things with small data sizes then go with something homegrown and leverage a TCP connection. It's much more to the point and you'll find the performance in real terms much better. Simple data structures and use fast operators to slice you data up as you need it.
Again as other posters have noted, battery usage is a big concern. You will eat a battery by literally burning a hole in your pocket if you are not careful. It is very easy to turn a battery that lasts 2 days into one that will last 6hours.
Lastly, don't trust the network if you are time sensitive. If you are not then a long poll over HTTP will be just fine for you. But if you are looking for high performance messaging, then be acutely aware that a mobile network is not an end-to-end TCP connection. Your requests will varying in trip time and latency.
So back to what you want to do with the app. As you are building for iOS (native obviously dictated) and Andriod, I would leverage Apple Push Services and their notification framework. Build you back end services to talk to that and also provide interfaces for non-apple devices (i.e. http or tcp level listeners). That way one platform and multiple 'gateways' for your apps. You can then do RIM via their push service too if you wanted to.
使用 TCP 套接字和您自己的协议比 HTTP 好得多,尤其是考虑到移动设备上资源的性质。 Erlang 会做得很好,但是让我们从你的协议开始。 Erlang 在这方面表现出色,尤其是 位语法< /a> 表达式。然而,您仍然可以根据需要使用纯文本。 JSON(需要解析器:在 Mochiweb 库Mochijson2.erl a>)和 XML(需要解析器:Erlsom)。
我个人曾参与过一个项目,其中我们在 Erlang 服务器和移动设备上使用原始 TCP 套接字。但是,根据您选择的端口号,沿途的路由器将根据服务提供商的安全策略阻止/丢弃数据包。不过,我仍然认为 HTTP 可以工作。人们在 Facebook Mobile 上聊天,从他们的设备发送 Twits 等,并且确信这些社交引擎使用某种长轮询或服务器推送或其他方式,但使用 HTTP。移动设备最近在功能上取得了进步。
推出自己的基于 TCP 的协议会带来许多挑战:端口选择、客户端和服务器上的数据解析、安全问题等。使用 HTTP 会让您思考实际问题,而不是花时间在客户端或服务器上纠正协议问题。您上面提到的 Android 和 IOS(Ipad、Iphone 等)等设备非常能够处理 HTTP COMET(长轮询)。我确信您遵循 Web 应用程序标准移动设备以及这些 W3C 移动网络最佳实践,您的应用程序将使用 HTTP 良好运行。
使用 HTTP 方法将加快工作速度,并且这些设备的 SDK 上有很多库,与滚动您自己的基于 TCP 的纯文本协议的情况相比,它们可以帮助您构建所需的解决方案原型。为了支持这一推理,请仔细阅读这些W3C 调查结果.
最后让我谈谈 HTTP 在这些设备上的好处。如果您要将 Web 技术用于移动设备,例如 Opera小部件、电话差距、 <一href="http://www.sencha.com/products/touch/" rel="nofollow noreferrer">Sencha Touch 和 JQuery Mobile,他们的 SDK 和库已经为您完成了优化,或者有详细记录的方法可以使您的应用程序变得高效。此外,这些技术还具有 API 来访问本机设备的资源,例如电池检查、SMS、MMS、GSM 广播频道、联系人、照明、GPS 和内存;全部作为 JavaScript 类中的 API。如果您使用像 J2ME,移动Python 或 Symbian C++ / Qt 与使用上述 CSS3、HTML5 和 JavaScript 工具等 Web 技术相比。使用上述 Web 工具将使您的应用程序可以通过 Ovi 商店轻松分发或 Apple Store,根据经验。
请注意,如果您使用 HTTP,测试将会很容易。您所需要的只是一个公共域,以便移动设备上的小部件可以通过互联网找到您的服务器。如果您使用自己的 TCP/IP 协议,网络路由器可能会破坏您使用的端口号,除非您计划使用端口 80 或其他众所周知的端口,但您的服务器 IP 仍然必须公开。有一个捷径:如果您将 TCP 服务器放置在与测试移动设备 Internet 连接相同的 ISP 后面,则 ISP 路由器将看到源和目的地都位于其网络后面。但总而言之,推出自己的协议存在一些挑战。
编辑:使用 HTTP,您将受益于 REST。在 Erlang 中实现的 Web 服务器(尤其是 Yaws 和 Mochiweb) 擅长 REST 服务。看看这篇文章:Yaws 的 RESTFUL 服务 。对于 mochiweb,有一篇有趣的文章: 使用 Mochiweb 的百万用户彗星应用程序分为 3 部分。此外,您可以查看解决方案针对这个问题。
Using TCP sockets with your own protocol rolled down is quite better than HTTP especially with the nature of resources on the mobile devices. Erlang will do quite well, however lets start from your protocol. Erlang excels well at this especially with the Bit Syntax expressions. However still, you could use plain text as you wish. JSON (would need a parser: Mochijson2.erl found in Mochiweb library) and XML (will need a parser: Erlsom).
I have personally worked on a project in which we were using raw TCP Sockets with our Erlang Servers and Mobile Devices. However, depending on the Port numbers you choose, Routers along the way would block/Drop packets depending on the security policies of service providers. However, i still think that HTTP can work. People chat on Facebook Mobile, send Twits e.t.c from their devices and am sure these social engines use some kind of Long Polling or Server Push or whatever but using HTTP. The mobile devices have advanced in capability of late.
Rolling your own TCP Based protocol comes with a number of challenges: Port selection, Parsing of data both at the client and server, Security issues e.t.c. Using HTTP will let you think of the actual problem than spending time correcting protocol issues at client or server. The Devices you've mentioned above like Android and IOS (Ipad, Iphone e.t.c) are very capable of handling HTTP COMET (Long polling). Am sure when you follow the standards for Web Applications on Mobile devices as well as these W3C Mobile Web Best Practices, your app will function well using HTTP.
Using HTTP methods will quicken the work and there are a lot of libraries on the SDKs of these Devices which would assist you prototype the solution you want as compared to the situation of rolling your own TCP-based plain text protocol. To back up this reasoning, look through these W3C findings.
Let me finally talk of the HTTP benefits on these Devices. If you are to use Web technologies for Mobile devices, such as Opera Widgets, Phone Gap, Sencha Touch, and JQuery Mobile, their SDKs and Libraries have Optimizations already done for you or have well documented ways in which your app can be made efficient. Further still, these technologies have the APIs to access the native Devices' resources like Battery check, SMS, MMS, GSM broadcast channels, Contacts, Lighting, GPS , and Memory; all as APIs in the JavaScript classes. It would become hard (inflexible) if you use native programming languages like J2ME, Mobile Python or Symbian C++ / Qt as compared to using Web technologies like CSS3, HTML5 and JavaScript tools mentioned above. Using the Web tools mentioned above will make your app easily distributable by say Ovi Store or Apple Store, from experience.
Take note that if you use HTTP, testing will be easy. All you need is a public Domain so the Widgets on the mobile device locates your servers over the Internet. If you role your own TCP/IP protocol, the Network Routers may be disruptive against the Port number you use unless you plan on using port 80 or another well known port, but then still your Server IP would have to be made Public. There is a short cut to this: if you put your TCP Server behind the same ISP as your testing Mobile's Internet connection, the ISP routers will see both source and destination as behind its Network. But all in all, there are challenges with rolling your own protocol.
Edit: Using HTTP, you will benefit from REST. Web Servers implemented in Erlang (especially Yaws and Mochiweb) excel at REST services. Look at this article: RESTFUL services with Yaws. For mochiweb, there is an interesting article about: A million User comet application using Mochiweb which is broken into 3 parts. Further still, you could look at the solution given to this question.
有适用于 Android 和 iOS 的 ZeroMQ 版本。 Java 和 ObjC 绑定也存在。
HTTP 是为具有大量响应的不频繁请求而创建的。对于传输大量小数据块来说效率非常低。在典型情况下,http 标头的大小可能是实际负载的两倍。 HTTP 唯一强大的一面是它的习惯性,它的“一刀切”业力。
如果你想要轻量且快速的解决方案,我想 ZeroMQ 可以是一个完美的解决方案。
There are ZeroMQ builds for android and iOS. Java and ObjC bindings exist as well.
HTTP was created for infrequent requests with large responses. It is highly inefficient for transferring very big amounts of small data chunks. In typical situation, http headers can be twice in size of actual payload. The only strong side of HTTP is its habitualness, its 'One size fits all' karma.
If you want lightweight and fast solution, I guess ZeroMQ can be a perfect solution.
使用 HTTP 而不是自定义服务的原因之一是它在传输级别上得到了广泛支持。
使用移动设备,用户可能在酒店、机场、咖啡店或公司 LAN 中使用 Wi-Fi。在某些情况下,这意味着必须通过代理进行连接。如果应用程序能够使用设备的代理设置进行连接,那么应用程序的用户将会感到最高兴。这提供了最不令人惊讶的地方——如果网页浏览正常,那么应用程序也应该可以正常工作。
HTTP 非常简单,因此编写一个接受来自自定义客户端的 HTTP 请求的服务器并不困难。如果您决定走这条路,最好的解决方案就是您不必支持的解决方案。如果您可以在 Erlang 中编写一些支持应用程序更改的内容,那么这听起来是一个合理的解决方案。如果您不愿意这样做,那么 PHP 或 J2EE 会因为廉价劳动力的可用性而获得加分。
虽然 HTTP 确实受益于广泛的支持,但一些成功的项目是基于其他协议的。 Sipdroid 开发人员发现持久的 TCP 连接确实可以极大地延长电池寿命。他们关于该主题的文章并未涉及服务器端,但确实提供了他们对客户的方法的高级描述。
One reason to go with HTTP instead of a custom service is that it's widely supported on a transport level.
With mobile devices, a user might be on Wi-Fi at a hotel, airport, coffee shop, or corporate LAN. In some cases this means having to connect via proxy. Your application's users will be happiest if the application is able to use the device's proxy settings to connect. This provides the least surprise -- if web browsing works, then the application should work also.
HTTP is simple enough that it isn't difficult to write a server that will accept HTTP requests from a custom client. If you decide to go this route, the best solution is the one that you don't have to support. If you can write something in Erlang that is supportive of application changes, then it sounds like a reasonable solution. If you're not comfortable doing so then PHP or J2EE gets bonus points for the availability of cheap labor.
While HTTP does benefit from being widely supported, some successful projects are based on other protocols. The Sipdroid developers found that persistent TCP connections do greatly improve battery life. Their article on the topic doesn't address the server side but it does give a high-level description of their approach on the client.
Erlang 非常适合您的用例。正如您已经指出的那样,为了节省手机电池寿命,我更喜欢使用 TCP 而不是 HTTP。
一般来说,设备和服务器之间的通信启动并运行会非常容易。您在两者之间使用的协议是需要最多工作的。然而,当使用 gen_fsm
你应该查看metajack的在 Erlang Factory 的演讲,重点介绍了他针对 iPhone 游戏的一个非常相似的用例的解决方案零食词。
Erlang is very well suited for your use case. I'd prefer using TCP over HTTP for the sake of saving battery life on the phone as you noted already.
Generally getting the communication between device and server up and running will be very easy. The protocol which you are using between the two is what will require most work. However writing protocols in Erlang is strikingly straight forward when using gen_fsm
You should checkout metajack's talk at the Erlang Factory which highlights his solution to a very similar use case for his iPhone game Snack Words.
我正在开发一个应用程序,该应用程序连接到 Microsoft http 服务器,该服务器具有与移动设备的长期 http/https 连接,以允许将推送类型数据发送到移动设备。它可以工作,但在移动端有很多小问题。
为了让客户端获取数据“数据包”,我们将 http 连接放入 Chucked Encoding 模式,以便每个数据包都在一个被卡住的数据包中。
并非每个移动设备上的所有本机 http API 服务都支持在“大量”数据到达时回调您,通常不会等到服务器上的所有数据都到达后才回调应用程序与数据。支持部分数据回调的平台是(我发现的):
不支持部分数据回调的平台:
对于不支持部分回调的平台,我们已经使用本机 sock 支持编写了自己的 http 连接代码,并提供了 chunked 编码支持。实际上并不难。
不要依赖一个chuck是您的数据包之一这一事实,http代理或本机http api实现可能会打破这一假设。
在具有此背景的 IOS 上多任务规则,意味着当您的应用程序处于后台时,您无法保持此连接。您确实需要使用苹果 推送通知 服务并遵守其限制。
永远不要相信移动蜂窝网络,我见过最奇怪的事情,比如服务器端看到http连接断开,然后重新连接(并重放原始http请求),而在移动端你看不到任何断开在连接中。基本上将连接视为不可靠,数据可能会丢失。我们最终实现了类似“tcp”的序列号方案,以确保我们不会丢失数据。
使用 http/https 可以更轻松地通过客户站点上的防火墙规则。
我不确定使用 http/https 长期连接是我们做过的最明智的决定,但它是在我出现之前很久就做出的,所以我必须忍受它的后果。
作为一种替代方案,我们也在研究网络套接字,但由于网络套接字规范处于不断变化的 atm 状态,而且通常不太好遵循,我不知道它是否会成功。
这就是我使用 http/https 作为长期实时连接的经验。
您的里程可能会有所不同。
I work on a application that connects to a Microsoft http server with long lived http/https connections to mobile devices to allow for push type data to be sent to the mobile. It works but there are lots of little gotcha's on the mobile side.
For the client to get 'packets' of data, we put the http connection into Chucked Encoding mode so that each packet is in one chucked packet.
Not all native http API services on each mobile will support calling you back when a 'chuck' of data has arrived, on the ones that don't normally wait until all the data from the server has arrived before calling the application back with the data. Platforms that support callbacks with partial data are (that I have found):
Platforms that don't support partial data callbacks:
For the platforms that don't support partial callbacks, we have written our own http connection code with chucked encoding support using the native sock support. It's actually not very hard.
Don't rely on the fact that one chuck is one of your packets, http proxies or the native http api implementations may break that assumption.
On IOS with this background multitasking rules, means you can't keep this connection going while your application is in the background. You really need to use Apples Push Notification service and live by it's limitations.
Never trust mobile cellular networks, I have seen the weirdest stuff going on like the server side seeing the http connection drop and then reconnect (and replay of the original http request) while on the mobile end you don't see any drop in the connection. Basically treat the connection as unreliable where data can go missing. We ended up implementing a 'tcp' like sequence number scheme to ensure we didn't lose data.
Using http/https makes it easier to get past firewall rules on customer sites.
I'm not sure using http/https long-lived connections was the wisest decision we ever made, but it was made long before I turned up so I have to live with the fall-out of it.
As a alterative, we are looking at web sockets as well, but with the web-socket spec in the state of flux atm and generally being not to good to follow, I don't know if it will work out or not.
So that is my experience with using http/https as a long-lived realtime connection.
Your milage may vary.