如何向 websocket 用户发送 AJAX 消息
How to send AJAX messages to websocket users
我已经在 Websockets 中实现了实时聊天,它的工作原理非常棒。我与 AJAX 轮询(以前存在)并排进行,因为我不想删除对旧浏览器的 AJAX 轮询支持,因此尽管 Websockets 将是首选,但我将轮询保持为一个选项。
我设置 websocket 代码的方式是:
- 使用 Websockets 将消息发送到适当的连接
- 在数据库中记录消息
AJAX 发送的方式是:
- 在数据库中记录消息
AJAX 投票的工作方式是:
- 检查用户上次检索房间消息的时间,并检索此后的所有消息
我有更多关于如何让两者协同工作的概念性问题。假设我有用户 A 和用户 B。如果用户 A 和用户 B 都使用 AJAX 轮询或都使用 websockets,则没有任何问题。它按您的预期工作。但是以用户 A 使用 websockets 而用户 B 使用 AJAX 轮询为例。
A→B
- 用户A通过websocket发送消息
- 聊天消息被发送到所有相关连接。在这种情况下,它只是回显给用户 A,因为用户 B 没有使用 websockets。
- 聊天消息被记录到数据库
- 用户B请求新消息,用户A的消息回传给他
B → A
- 用户 B 通过 AJAX
发送消息
- 消息被保存在数据库中
- ?
这就是我挂断电话的原因。 Websocket -> AJAX 用户消息之所以有效,是因为该消息最终在数据库中可以被 AJAX 用户轮询。但是 websocket 用户根本不轮询数据库,因此来自 AJAX 用户的消息无法进入管道。目前,websocket 用户看不到来自 AJAX 用户的任何消息。他们只有在重新加载整页时才能看到它们,此时所有消息都会直接从数据库中检索。
允许通过 websocket 将来自 AJAX 用户的消息以某种方式发送给相关 websocket 用户的适当方法是什么?基本上,我怎样才能在另一个方向上沟通?
关于这个主题,我唯一能找到的是 this slideshow - 但是,我没有使用长轮询,而且我不完全确定“提供”是什么意思网络套接字应用程序。这是否意味着让 websocket 服务器承担检查新 AJAX 消息的责任?没有办法从 AJAX 脚本“推送”到 websocket 服务器吗?
简单的解决方案:
当您将消息保存到数据库中时,也将其推送到 Websocket 客户端。
感谢 ADyson 提供了有关如何处理此问题的一些想法。这就是我最终做的:
我让我的 JS 客户端每隔几秒 ping 服务器一次。对于 AJAX 用户,它更频繁,因为他们需要轮询消息。对于 Websocket 用户,他们不需要轮询 websocket 消息,因此他们每 15s 轮询一次以“签到”。这具有本质上为每个客户端充当无限循环的好处,这正是这个想法所需要的。
我所做的基本上是在 messages
table 中添加一列来跟踪消息来源:0
for AJAX and 1
对于 WebSocket。然后,我修改了检索消息的函数以接收 $ajaxOnly
参数。当我在 AJAX 投票中调用它时,它是 false
。对于 websocket 投票,我用 true
代替。结果是对于用户所在的所有房间,它轮询数据库并检查是否有任何新的 AJAX 消息。如果有,它会将它们发送回客户端。
有 2 个注意事项:
- 消息将乱序显示。 Websocket 消息是实时中继的,因此在 Websocket 消息之前发送的 AJAX 消息可能会更早地显示给另一个 AJAX 用户,但稍后会显示给其他 Websocket 用户。
- 这是不是实时的。它和你的轮询间隔一样慢,在我的例子中,websockets 是 15 秒,因为轮询是非常密集的数据库。 AJAX 民意调查更加频繁,因为他们需要获得任何消息。
这不是一个完美的解决方案,但它确实达到了允许 AJAX 消息在 近 实时显示给 websocket 用户的目标。对我来说,我想完全支持 AJAX 和 WebSocket,但是 AJAX 更多的是为了兼容性,理想情况下大多数人都会使用 WebSockets,所以这是事实很棒 的解决方案并不太关心我,因为它确实完成了工作。
如果您希望有一个实时解决方案(就像我一样),您会对此感到失望,但这至少是一个可行的解决方案,所以我一直采用它直到出现更好的解决方案。您可以通过增加客户端 ping 您的服务器的频率来使其接近实时。
我已经在 Websockets 中实现了实时聊天,它的工作原理非常棒。我与 AJAX 轮询(以前存在)并排进行,因为我不想删除对旧浏览器的 AJAX 轮询支持,因此尽管 Websockets 将是首选,但我将轮询保持为一个选项。
我设置 websocket 代码的方式是:
- 使用 Websockets 将消息发送到适当的连接
- 在数据库中记录消息
AJAX 发送的方式是:
- 在数据库中记录消息
AJAX 投票的工作方式是:
- 检查用户上次检索房间消息的时间,并检索此后的所有消息
我有更多关于如何让两者协同工作的概念性问题。假设我有用户 A 和用户 B。如果用户 A 和用户 B 都使用 AJAX 轮询或都使用 websockets,则没有任何问题。它按您的预期工作。但是以用户 A 使用 websockets 而用户 B 使用 AJAX 轮询为例。
A→B
- 用户A通过websocket发送消息
- 聊天消息被发送到所有相关连接。在这种情况下,它只是回显给用户 A,因为用户 B 没有使用 websockets。
- 聊天消息被记录到数据库
- 用户B请求新消息,用户A的消息回传给他
B → A
- 用户 B 通过 AJAX 发送消息
- 消息被保存在数据库中
- ?
这就是我挂断电话的原因。 Websocket -> AJAX 用户消息之所以有效,是因为该消息最终在数据库中可以被 AJAX 用户轮询。但是 websocket 用户根本不轮询数据库,因此来自 AJAX 用户的消息无法进入管道。目前,websocket 用户看不到来自 AJAX 用户的任何消息。他们只有在重新加载整页时才能看到它们,此时所有消息都会直接从数据库中检索。
允许通过 websocket 将来自 AJAX 用户的消息以某种方式发送给相关 websocket 用户的适当方法是什么?基本上,我怎样才能在另一个方向上沟通?
关于这个主题,我唯一能找到的是 this slideshow - 但是,我没有使用长轮询,而且我不完全确定“提供”是什么意思网络套接字应用程序。这是否意味着让 websocket 服务器承担检查新 AJAX 消息的责任?没有办法从 AJAX 脚本“推送”到 websocket 服务器吗?
简单的解决方案: 当您将消息保存到数据库中时,也将其推送到 Websocket 客户端。
感谢 ADyson 提供了有关如何处理此问题的一些想法。这就是我最终做的:
我让我的 JS 客户端每隔几秒 ping 服务器一次。对于 AJAX 用户,它更频繁,因为他们需要轮询消息。对于 Websocket 用户,他们不需要轮询 websocket 消息,因此他们每 15s 轮询一次以“签到”。这具有本质上为每个客户端充当无限循环的好处,这正是这个想法所需要的。
我所做的基本上是在 messages
table 中添加一列来跟踪消息来源:0
for AJAX and 1
对于 WebSocket。然后,我修改了检索消息的函数以接收 $ajaxOnly
参数。当我在 AJAX 投票中调用它时,它是 false
。对于 websocket 投票,我用 true
代替。结果是对于用户所在的所有房间,它轮询数据库并检查是否有任何新的 AJAX 消息。如果有,它会将它们发送回客户端。
有 2 个注意事项:
- 消息将乱序显示。 Websocket 消息是实时中继的,因此在 Websocket 消息之前发送的 AJAX 消息可能会更早地显示给另一个 AJAX 用户,但稍后会显示给其他 Websocket 用户。
- 这是不是实时的。它和你的轮询间隔一样慢,在我的例子中,websockets 是 15 秒,因为轮询是非常密集的数据库。 AJAX 民意调查更加频繁,因为他们需要获得任何消息。
这不是一个完美的解决方案,但它确实达到了允许 AJAX 消息在 近 实时显示给 websocket 用户的目标。对我来说,我想完全支持 AJAX 和 WebSocket,但是 AJAX 更多的是为了兼容性,理想情况下大多数人都会使用 WebSockets,所以这是事实很棒 的解决方案并不太关心我,因为它确实完成了工作。
如果您希望有一个实时解决方案(就像我一样),您会对此感到失望,但这至少是一个可行的解决方案,所以我一直采用它直到出现更好的解决方案。您可以通过增加客户端 ping 您的服务器的频率来使其接近实时。