我们正在Android中构建聊天应用程序。我们正在考虑使用HTTP REST API发送出站邮件。与使用WebSockets或XMPP(这似乎更像是转移聊天消息的事实标准)相比,想知道它是一种好方法还是有任何缺点?
我能想到的一些优点/缺点是:
+ HTTP端点易于在服务器端水平扩展(这是一个主要问题)
与HTTP相比,Websockets的学习曲线更陡峭
- 与websockets相比,HTTP消息的负载更大
根据这份文件,似乎Facebook最初使用AJAX来处理聊天消息:
https://www.erlang-factory.com/upload/presentations/31/EugeneLetuchy-ErlangatFacebook.pdf
答案 0 :(得分:12)
我们可以使用REST API进行聊天消息传递,但恕我直言,XMPP是更好的选择。让我们考虑一下XMPP提供的内容。
支持TCP传输的XMPP还提供HTTP(通过轮询和绑定)和 websocket 传输。阅读XMPP via HTTP and WebSocket transports
从XMPP的角度来理解每种传输的优缺点会很有趣。
XMPP可以通过两种方式使用HTTP:轮询 [18]和绑定。
通过HTTP轮询进行XMPP
民意调查 方法,现已弃用,实质上意味着存储在a上的消息 服务器端数据库正在被定期提取(和发布) XMPP客户端通过HTTP'GET'和'POST'请求。
XMPP over HTTP Binding(BOSH)
绑定方法被认为比Polling方法中的常规HTTP'GET'和'POST'请求更高效,因为与其他HTTP轮询技术相比,它减少了延迟和带宽消耗
然而,这也带来了一个缺点,即套接字长时间保持打开状态,等待客户的下一个请求
绑定方法,使用Bidirectional-Stream Over Synchronous HTTP实现 ( BOSH ),[19]允许服务器尽快将消息推送到客户端 发送。 此推送通知模型比效率更高 轮询,许多民意调查没有返回任何新数据。
如果我们了解the BOSH technique的工作方式,那就太好了。
BOSH采用的技术,有时称为“HTTP long 轮询“,减少了其他HTTP上的延迟和带宽消耗 投票技巧。当客户端发送请求时,连接 经理不会立即发送回复;相反它持有 请求打开,直到它有数据实际发送到客户端(或 同意的不活动时间已经过去了)。然后是客户 立即向连接管理器发送新请求,继续 长轮询循环。
如果连接管理器没有任何数据要发送到客户端 在一段同意的时间[12]之后,它会发送一个回复 空的。这与空白保持活动的目的相似 或XMPP Ping(XEP-0199)[13];它有助于保持套接字连接活动 这可以防止一些中介(防火墙,代理等) 默默地放下它,并帮助检测合理的断裂 时间量。
XMPP over WebSocket绑定
XMPP支持 WebSocket绑定,这是一种更有效的传输
可能更有效的实时消息传输是 WebSocket,一种提供双向全双工的网络技术 单个TCP连接上的通信信道。 XMPP结束了 WebSocket绑定在IETF提议的标准RFC 7395中定义。
说到学习曲线,是的,您可能很想使用REST API,但现在有几个资源需要了解Android and XMPP和XMPP server softwares可以用来运行自己的API XMPP服务,可通过Internet或局域网进行。在决定你的架构之前,值得花费这些努力。
答案 1 :(得分:7)
我认为REST方法可以用于聊天。我们假设:
如果我理解正确,你的问题就是最后一点。
客户端向http://chat.example.com/conversations/123发布了一条outboud消息后,它将关闭http连接。
缺点是在这种情况下根本不可能接收入站消息。您将需要一个不同的频道(可能只是Google cloud messaging)。
相反,WebSockets和XMPP使连接保持活动状态,因此它们可以毫无延迟地接收消息。但两者的缺点确实是,在可扩展性方面,这代表了服务器上的成本;以及电池使用量方面的客户成本。
在服务器上:
在客户端:
答案 2 :(得分:5)
建议不要将HTTP Rest API用于聊天或类似的实时应用程序。
一些概述..
聊天客户端要求
朋友列表提取
查看在线/离线朋友
点1是你启动聊天客户端之后的一次性工作,所以可以通过简单的休息调用来完成,因此没有复杂的开销。
在p2p客户端的情况下,所有点都需要持久检查来自服务器或其他部分的数据。这将使您创建长或短轮询休息呼叫以监视新数据或其他更新。
HTTP Rest客户端问题
这不是一个保持活动类型的通信,因为你必须进行多个http连接,这将有太多的开销,它将变得过于迟缓。因为重新连接在HTTP调用中非常昂贵。
**网络套接字或XMPP ** 它们是双工通信模式,非常擅长处理增量数据推送,并且您不会再次创建新的http连接,因此它可以提供真正流畅的性能。
另一种解决方案 如果你遇到一些遗留系统,你必须使用其余的api模式。
尝试 CometD 它是websockets和ajax轮询的混合方法,它可以为您提供近乎实时的通信,以及通过回退ajax轮询机制来处理不支持websockets的客户端。它还使用各种优化来避免一次又一次地重新连接。
你也可以尝试 Socket.io ,这也是一种解决这类用例的神奇技术
答案 3 :(得分:2)
简短回答编号
我不会开始一个新项目或建议开始一个新项目(因为你提到重新开始)需要一个依赖于HTTP的实时双向通信 - 作为无状态协议。您可能会感到安慰,因为连接仍然存在,但无法保证。
当HTTP用作请求和响应样式以及何时被视为无状态时,您的+ HTTP endpoint is easy to scale horizontally on server side
专业人员是上下文中的专家。当你本身需要保持连接存活时,它变得有点没有实际意义(尽管不完全)。
HTTP确实提供了您未在此处提及的其他优势。
- 当其他端口可能被阻止时,HTTP很容易处理公司防火墙代理。
这是其他人提到的Web上的WebSockets或XMPP将具有更好的成功率。
答案 4 :(得分:1)
这取决于。你认为你的申请是"在线聊天"?您是否需要在线状态指示器或键入指示器?这些功能需要连续连接。但是,您可以将另一组聊天应用程序描述为"应用程序内消息传递"启用。这些应用程序在某种后端存储会话和会话列表;只需在其他设备上安装该应用并登录,即可在此类应用中看到您的对话。这些应用程序没有任何存在指示或活泼的感觉。
虽然我还没有使用XMPP实现任何应用程序,但就消息持久性而言,您在XMPP(开箱即用)中找到的最持久性是持久的,直到交付,类似发短信也许您可以通过在节点传递并将它们存储在您自己的数据库中时捕获节来为XMPP构建存储/恢复机制。但如果你不需要完整的聊天"经验,使用数据库,HTTP服务和推送通知(以通知更新的线程)似乎是具有消息传递功能的应用程序的可靠路径 - 我打算在iOS&我自己的Android应用程序。
如果您为此找到了任何良好的开源架构/ API设计,请告诉我。