推送通知需要使用websocket吗?

49

我在服务器端使用 PHP,客户端使用 HTML 和 JavaScript。

我正在制作一个应用程序,利益相关者输入消息,该消息实时广播给组中的多个接收者。

我在谷歌上做了一些研究,了解到需要使用 WebSocket 或 Comet 进行实时推送通知。对于向用户发送大量通知,WebSocket 或 Comet 是否是必需的?

我的理解正确吗?有任何参考资料可以开始使用吗?

3个回答

90
如果客户端是浏览器,那么标准浏览器连接服务器的唯二方式是通过Ajax(例如http)请求或webSocket连接。因此,如果您希望客户端从外部获取通知,则必须使用这两种机制之一。
HTTP请求是短暂的。客户端向服务器发出请求,服务器做出响应。HTTP请求非常适用于客户端请求从服务器获取信息。它们不太适合服务器向客户端发送信息,因为通常客户端没有连接。有一些hack和解决方法,其中客户端会在某个时间间隔内轮询服务器,甚至服务器使用长时间运行的请求来尝试模拟“推送”类型系统,但它们最多只能算是次优的hack。
webSockets是持续连接。客户端连接并且连接保持有效,直到双方都想结束为止。这使得双方都可以随时向对方发送消息。这意味着服务器可以随时向客户端“推送”数据。webSockets对于推送连接非常高效,因此建议使用(这是它们设计的主要功能之一)。
Comet是一个最初为了在WebSockets被发明之前和广泛支持之前使用HTTP尝试“黑客”或“模拟”推送而构建的库。除非您使用的是不支持WebSocket的旧浏览器,否则我想不出为什么要使用Comet而不是WebSocket。

因此,如果您正在尝试向浏览器进行“实时服务器推送”,那么您必须从客户端拥有一个连续连接的套接字,这意味着WebSocket(或构建在WebSocket上的某些内容,如Socket.IO)。

对于具有访问手机SDK的手机应用程序,您可以使用内置于操作系统中的“推送”系统将一些消息从服务器推送到客户端。虽然这与双向WebSocket通道不完全相同,但由于您询问了“推送通知”,因此Android和IOS中提供的操作系统推送服务也可以成为从服务器向客户端推送通知的选项。这里有iOS通知Google Cloud Messaging的信息。

截至2016年,除了微软浏览器(Edge或IE尚未支持),现代浏览器都可以使用服务器推送事件将数据从服务器推送到客户端。这是一个浏览器兼容性表。服务器推送事件使用长时间的HTTP连接、特殊的MIME类型和支持客户端,以便能够随时从服务器向客户端发送事件。与WebSockets不同,服务器推送事件仅是单向的(从服务器到客户端)。然后,客户端将使用传统的Ajax调用,以便能够将数据发送到服务器(而使用WebSocket,则可以通过同一WebSocket连接双向发送数据)。

这里有一个关于服务器推送事件如何工作的好描述:服务器推送事件实际上是如何工作的?


手机应用中的推送系统是什么意思?是指推送通知吗?这与WebSockets的行为不同... - User
1
@Ixx - Android和iOS都内置了推送服务。这里有关于iOS通知Google Cloud Messaging的信息。它们显然不同于webSockets(也不是用来替代的),但如果你只想偶尔从服务器向手机发送更新,这可能是最有效的方法。 - jfriend00
是的,我知道这可能会让人感到困惑,因为它似乎被建议用于Websockets,但实际上不能这样使用。 - User
1
@Ixx - OP正在询问“推送通知”的选项。我回答说,如果您的目标是具有自定义应用程序的移动设备,则操作系统推送服务是推送通知的一种选择。 - jfriend00
在你的最后一段中,你从Websockets跳到“用于手机”,读起来好像这是手机的等效物,但实际上完全不同,正如你自己所说。而且Websockets也适用于手机。 - User
添加了有关服务器推送数据到客户端的服务器发送事件的注释。 - jfriend00

4
你的客户端应用是单页应用(SPA)吗? 这非常重要,因为如果不是,每当客户端更改页面时,与WebSocket服务器的连接将会丢失。 在这种情况下,您需要管理队列,因为如果利益相关者在一个客户端断开连接时发送多播请求,客户端将无法接收任何内容。 轮询也无法解决此情况,并且它是一种可怕的解决方案,因为具有典型互联网计划的移动客户端(例如)将消耗兆字节的无用“ping”流量。 轮询的一个真实例子就像是一个坐在车里的孩子每分钟都问他父亲是否到达目的地!
那么,有没有不使用SPA的解决方案呢? 是的,可以使用共享存储介质,在利益相关者和客户之间共享,只使用WebSocket来唤醒在线客户端,告诉他们有新的消息,去查看!
每当客户端打开一个页面时,它还会从后端接收未读通知,从存储中获取。当利益相关者想要通知某些事情时,它只需将通知消息存储在共享存储介质中,并向通知服务器发送一个“脉冲”。 通知服务器将向在线客户端转发“脉冲”(以防万一有人卡在某个页面上阅读)。 如果由于客户端正在更改页面而丢失了“脉冲”,那么也没有问题,因为客户端将从存储中提取通知。 每个页面都将包含此逻辑: 检索未读通知的数量(服务器端) 在5秒后连接到通知服务器(JavaScript端)。 希望这可以帮助你。

2
我建议使用webSocket相比其他选项更加高效,为什么呢?当客户端接收到有关服务器发生更改的通知时,无需创建AJAX调用以获取该更改,可以通过与相同的webSocket连接更轻松地向客户端发送。这意味着更有效的代码和更快速运行的应用程序!

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