使用HTTP REST API在聊天应用中是否可行?

32
我们正在Android上构建一个聊天应用程序。 我们考虑使用HTTP REST API发送出站消息。 想知道与使用WebSockets或XMPP(似乎更成为传输聊天消息的事实标准)相比,它是否是一个好方法或有任何缺点?
我能想到的一些优缺点是:
- HTTP端点在服务器端易于水平扩展(这是主要关注点) - 与HTTP相比,学习Websockets的曲线较陡 - 与WebSockets相比,HTTP消息的负载将更大
根据这份文件,甚至Facebook最初也使用AJAX来处理聊天消息:

https://www.erlang-factory.com/upload/presentations/31/EugeneLetuchy-ErlangatFacebook.pdf


Websocket或XMPP是一个不错的选择。您可以使用https://kaazing.com/products/kaazing-websocket-gateway/,也可以使用SIP(创建点对点)。我不是专家,只是发表评论。 - mubeen
在Facebook的演示中,他们说他们使用了Comet和ajax。我没有看到他们说他们使用了REST。而且很明显,他们今天仍然为Web客户端使用ajax(或者某些aja*)。 - rds
为什么不使用HTML5 WebSocket?它比定期进行POST/GET更好,这使得聊天与实时聊天有些脱节。 - lostincomputer2
5个回答

20

我们可以使用REST API进行聊天消息传递,但在我看来,XMPP是更好的选择。让我们看看XMPP有什么优势。

除了支持TCP传输外,XMPP还提供了HTTP(通过轮询绑定)和websocket传输方式。阅读通过HTTP和WebSocket传输的XMPP

从XMPP的角度来看,了解每种传输的优缺点是很有趣的。

XMPP可以以两种方式使用HTTP:轮询 [18]和绑定

通过HTTP轮询的XMPP

该轮询方法现已被弃用,基本上意味着存储在服务器端数据库中的消息通过HTTP“ GET”和“ POST”请求定期由XMPP客户端获取(和发布)。


XMPP over HTTP Binding (BOSH)

与轮询方式下的常规HTTP“GET”和“POST”请求相比,该绑定方法被认为更加高效,因为它减少了延迟和带宽消耗,超过了其他HTTP轮询技术。

然而,这也带来一个缺点,即套接字会等待客户端的下一个请求而保持打开状态。

使用同步HTTP上的双向流(BOSH)实现的绑定方法允许服务器在发送消息后立即将其推送到客户端。这种推送模型的通知比轮询更有效,因为许多轮询返回没有新数据。

如果我们理解 BOSH技术的工作原理,那就太好了。

BOSH所采用的技术有时被称为“HTTP长轮询”,相对于其他HTTP轮询技术,它可以降低延迟和带宽消耗。当客户端发送请求时,连接管理器不会立即发送响应,而是将请求保持打开状态,直到实际有数据要发送给客户端(或者经过了一定时间的不活动)。然后客户端立即向连接管理器发送新的请求,继续进行长轮询循环。如果连接管理器在一定时间内没有数据要发送给客户端,则会发送一个带有空内容的响应。这类似于空格保持活跃或XMPP Ping(XEP-0199)[13],它有助于保持套接字连接处于活动状态,防止某些中间件(防火墙、代理等)静默丢弃它,并有助于在合理的时间内检测到断开连接。

WebSocket绑定的XMPP

XMPP支持WebSocket绑定,这是一种更高效的传输方式

对于实时消息传递而言,WebSocket可能是一种更有效的传输方式。它是一种Web技术,提供了通过单个TCP连接进行双向全双工通信的通道。 XMPP over WebSocket绑定在IETF建议标准RFC 7395中定义。

谈到学习曲线,你可能会尝试使用REST API,但现在有几个资源可以了解Android和XMPP以及XMPP服务器软件,您可以使用它们来运行自己的XMPP服务,无论是在Internet上还是本地区域网络上。在确定架构之前,值得花费这些努力。


11

我认为 REST 方法可以用于聊天。假设:

如果我理解正确,您的问题是关于最后一点。

一旦客户端已将传出消息发布到 http://chat.example.com/conversations/123,它将关闭 http 连接。

缺点是在这种情况下根本无法接收入站消息。您需要一个不同的通道(也许只需使用 Google 云消息传递)。

相反,WebSockets 和 XMPP 保持连接处于活动状态,因此它们可以无延迟地接收消息。但是两者的缺点确实是这代表了服务器方面的可伸缩性成本;以及在客户端方面代表了电池使用成本。

在服务器上:

  • 套接字是相对稀缺的资源
  • 如果客户端有一个开放的连接,那么无法将其移动以进行负载平衡(但您确实可以移动客户端吗?这取决于各个层次的责任)

在客户端上:

我对android上WebSocket的支持没有任何头绪。

7

不建议在聊天或类似实时应用中使用HTTP Rest API。

概述...

聊天客户端要求

  1. 获取好友列表

  2. 检查在线/离线好友

  3. 实时获取聊天消息并发送消息。

  4. 接收交付/阅读等通知。

第1点是启动聊天客户端后的一次性工作,因此可以通过简单的rest调用完成,无需复杂的开销。

其他所有点都需要对服务器或其他部分进行持续的数据检查,以防P2P客户端的情况。这将使您创建长轮询或短轮询rest调用以监视新数据或其他更新。

HTTP Rest客户端的问题

它不是保持活动状态的通信类型,因此您将不得不进行多个HTTP连接,这将产生过多的开销,导致过于滞后。由于重新连接在HTTP调用中非常昂贵。

Web sockets或XMPP
它们是双工通信模式,非常擅长处理增量数据推送,并且不会再创建新的HTTP连接,因此可以提供非常流畅的性能。
另一种解决方案
如果你被一些遗留系统所困扰,必须使用rest API模式。
尝试CometD,它是WebSockets和ajax轮询的混合方法,将为您提供接近实时的通信,并在不支持WebSockets的客户端上通过回退到ajax轮询机制来工作。此外,它使用各种优化来避免反复重新连接。 CometD link 您还可以尝试Socket.io,这也是解决这类用例的惊人技术。

3
简短回答是不行的。如果需要依赖于HTTP进行双向通信,则不建议开始新项目或推荐开始新项目(因为您提到了重新开始),因为HTTP是无状态协议。虽然连接保持活动,但并没有保证。
在服务器端,您的“+ HTTP端点易于水平扩展”确实是一个优点,但前提是HTTP被用作请求和响应样式,并且被认为是无状态的。当您本质上需要保持连接活动时,这个观点变得有些无关紧要(尽管不完全如此)。
HTTP还提供了另一个优点,您在这里没有提到。
HTTP易于处理企业防火墙代理,其他端口可能会被阻止。
这就是其他人提到的WebSockets或XMPP over HTTP将具有更好的成功率的地方。

2
这要看情况。你认为你的应用是“实时聊天”吗?你需要存在指示器或打字指示器吗?这些功能需要持续连接。但还有另一组聊天应用程序,你可以将其描述为启用“应用内消息”。这些应用程序在某种后端上存储对话和对话列表;只需在另一个设备上安装该应用并登录,您就可以在此类应用上查看您的对话。这些应用没有任何存在指示器或实时感。
虽然我还没有使用XMPP实现任何应用程序,但就消息持久性而言,XMPP(开箱即用)提供的最持久的可能是persist-until-delivered,类似于短信。也许您可以通过捕获通过的数据包并将其存储在自己的数据库中来构建XMPP的存储/恢复机制。但如果您不需要完整的“聊天”体验,则使用数据库、HTTP服务和推送通知(以通知更新的线程)似乎是具有消息功能的应用程序的可靠路径——我现在打算在自己的iOS和Android应用程序中实现此功能。
如果您发现了任何好的开源模式/ API设计,请告诉我。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接