-3

我想使用 jQuery 和 PHP 编写一个聊天应用程序。我需要帮助的部分是实时用户“Evx”正在输入一条消息,然后将该消息实时显示给所有其他用户。这类似于 Skype 有一支笔 ../ 以及 Facebook 如何在用户键入时发出通知。

我需要的是有关如何轻松完成实时“用户正在打字”的逻辑步骤和信息的一些帮助,但仍然可以像任何其他方式一样工作。

这是我迄今为止尝试过的:

//time delay before ajax call
var delay = (function() {
    var timer = 0;
    return function(callback, ms) {
        clearTimeout(timer);
        timer = setTimeout(callback, ms);
    };
})();

$('#usermsg').keydown(function() {
    if ($('#usermsg').val().length === 5) {
        delay(function() {
            $.ajax({
                url: "addusertyping.php",
                cache: false,
                success: function() {

                }
            });
        }, 5000);
    }
});

$('#usermsg').keyup(function() {
    if ($('#usermsg').val().length >= 6) {
        // here I should basically check for 
          // an update from server or what not.
    }
});​

有人可以使用我上面尝试的作为起点,解释有关如何实现用户实时输入的步骤和信息吗?

4

1 回答 1

13

Facebook 和 Google Talk 等网站在实现聊天时使用的方法是使用利用 Comet 或 Reverse AJAX 的 Web 请求/响应模型的解决方案。

网络 1.0:

在传统的 Web 1.0 实现中,例如您的,浏览器向服务器发起请求。服务器使用客户端代码在视图中呈现的数据进行响应。

当我们只是将用户从一个页面移动到另一个页面时,或者当我们响应用户发起的事件时,这非常有用。但是,这种方法在管理由服务器发起的事件时存在固有缺陷。

在您的示例中,为了模拟实时更新,您必须通过连续轮询请求来检查服务器以检查更新。这相当于汽车后座上的小孩不断地问他的父母“我们到了吗?我们到了吗?” 一遍又一遍没有失败。这不仅会占用大量带宽,而且当连接的客户端数量增加时会在服务器上造成沉重的负载。

彗星/反向 AJAX:

由于服务器无法在没有请求的情况下向浏览器发起响应,因此使用一种称为“反向 AJAX”或“Comet”的技术来模拟服务器向客户端推送事件通知的过程。

Comet 背后的一般前提是浏览器打开与服务器的连接,然后服务器无限期地保持该连接打开。当服务器有一个更新需要传递给所有连接的客户端时,它会将响应发送回客户端,完成请求/响应周期。收到响应后,客户端立即向服务器发送另一个请求,服务器再次保持打开状态,直到下一次更新。

有可用于 PHP 的 Comet 解决方案,因此您可以使用现有平台完成此任务;但是,我不能推荐任何。您还需要一个客户端库来帮助打开 Comet 连接。查看Dojo Cometd JavaScript 库

Comet 是实现聊天解决方案的两个高级解决方案之一,另一个是 WebSockets。但是,某些浏览器仍然缺乏对 WebSockets 的支持。

在寻找促进 Comet 的库时,选择促进 Continuations 的库也是一个好主意,这有助于确保可以释放等待发送响应的线程以执行其他任务,而不是无所事事地等待。有了这样的解决方案,一些 Comet 服务器可以轻松扩展到超过 20,000 个连接!

这是一篇描述如何在 PHP 上实现 Comet的文章。此外,您可能会发现这个 StackOverflow 问题很有用,因为它描述了在 PHP 上使用 Comet 的挑战

设计注意事项:

我们在开发聊天解决方案时犯的第一个错误之一是没有将消息视为更抽象事物的子类。相反,我们从服务器发送到前端的信息只是一条“聊天消息”。然而,随着产品的进步,我们很快发现同一个 Comet 连接可以用于向浏览器发送命令,而不仅仅是消息。

因此,要实现“用户正在键入”,您可能需要 JavaScript 中的处理程序首先确定来自服务器的更新是新消息,还是“显示用户 XYX 正在键入”命令。一个好的设计还可以确保您可以将 Comet 连接用于其他类型的更新,以及从服务器启动的更新。

最后,您的用户输入消息应该有某种延迟,这样当用户输入时,他或她的浏览器只会每 X 秒通知一次服务器。如果您将用户键入绑定到一个按键事件,该事件只是用 AJAX 请求敲击服务器,那么您只是将 Comet 连接降级为轮询。

在接收端,您很可能希望实现超时功能,以便如果正在输入的用户停止向服务器发送“用户输入”请求,则用户输入消息会自动消失。或者,如果浏览器在他或她的文本框为空时发送请求,例如当用户在输入的文本上退格时,该用户的浏览器可以发送“用户不再键入”消息。

简单的解决方案?:

最后,我想补充一点,这将涉及一个学习曲线,因为您必须从服务器将数据推送到客户端的角度来考虑 Web。这将涉及您的大量研究和奉献,以及尝试示例并真正深入了解您应该如何处理应用程序的设计。这是迄今为止掌握这项技术的最佳方法之一,但它也可能令人生畏。请务必花时间学习这些示例,自己尝试一下,如果遇到困难,您可以随时寻求帮助。

于 2012-05-13T01:32:24.597 回答