【问题标题】:HTML5 simple chatroomHTML5 简单聊天室
【发布时间】:2012-01-15 16:23:41
【问题描述】:

我想做的是一个简单的 HTML5 聊天室,没什么特别的,一旦有人说了什么,它就会将它发送给当前连接到服务器的每个人,仅此而已。没有存储,没有什么复杂的。不过,它必须灵活,我的网站应该能够根据需要自动创建单独的聊天室。我看过很多演示和示例,但所有这些都要求我安装 node.js 或类似的需要终端访问的东西(我没有)。我目前正在其中一个免费的网站主机上运行,​​它为您提供了一个 ftp 客户端、一个 mysql 数据库、一些 php 支持,仅此而已。有没有办法做到这一点?或者我可能遗漏了一些东西,有没有办法在这些服务器上安装软件包?也许有人知道获得终端访问权限的方法?任何形式的帮助将不胜感激,谢谢。

【问题讨论】:

  • 如果你有 root 访问权限(你现在没有),你可以安装 tornado/node.js 等。现在你可以做聊天室,只需发送许多 ajax 请求来检查新的消息,虽然它不会那么快。如果你真的需要root权限可以考虑购买VPS,它不会花费太多,但你可以安装自己的软件(将apache换成nginx、tor​​nado、cassandra...)
  • 如果没有 node.js 之类的工具,你无法推送到客户端。您应该按时间间隔检查 ajax 到服务器,而不是推,尝试拉
  • 如果你真的想锻炼你的 HTML5 肌肉,大多数浏览器都有 WebSockets 或服务器发送事件的实现。如果不支持,请尝试使用它们并回退到 ajax/long 轮询。

标签: php html chatroom


【解决方案1】:

去过那里。做对并非易事。

我认为您必须做出一个重要决定:您是希望聊天真正即时进行,还是可以延迟 2 秒,直到每个人都看到新消息。

如果延迟没问题,您实际上可以每 2 秒轮询一次服务器以查看是否有新消息可用。没有人喜欢延迟,但取决于你想做什么,它可能不是那么糟糕。然后,服务器将检查每个请求的数据库/文件并返回更新。这是一个非常简单的解决方案,并且有效。 (如果您认为每 2 秒轮询一次会浪费资源并在服务器上造成不必要的负载……请继续阅读,替代方案可能会更糟。)

完全即时的聊天要求服务器可以立即向客户端发送新数据,而无需等待客户端请求。 HTTP 本身并不支持这一点,如果您不想使用任何 Flash/Java,我知道的唯一方法是使用彗星请求。这些请求(通常是 AJAX)会故意在服务器上挂起一段时间,然后在需要发送到客户端的新数据可用或发生超时时准确返回。每次彗星请求返回时,客户端都会处理数据并立即发出另一个彗星请求,该请求将再次挂起,直到有新数据可用。我相信每个纯 HTML/JS 的聊天网站都是这样做的(Omegle、Facebook 等)。

现在,这是最简单的部分。但是如何在服务器上实现呢?让我们看一下这种情况:您在聊天中有 10 个用户,这意味着 10 个客户端每个都有一个等待新数据的悬空彗星请求。其中一位用户在聊天中写入了一些内容,这会导致向服务器发出附加请求以发布文本。您如何使服务器上的 PHP 脚本的这一次执行导致其他 10 次执行停止等待并返回新数据? (您可以用 Perl 或任何东西代替 PHP。)您将需要允许多个脚本执行相互通信的东西。 (或者 PHP 代码本身可能每秒轮询一次数据库,但这又会引入延迟。)在这些脚本语言中,任何形式的进程间通信 (IPC) 都很困难,尤其是您不知道使用哪种模型时Web 服务器用于执行它们。例如,Apache 可以为每个请求创建一个进程,或为每个请求创建一个线程,或者两者兼而有之。但也许你的主机使用 IIS 或其他东西,所以在这种情况下很难进行 IPC。我最终做的是在 PHP 中创建一个自己的服务器组件,它一直在运行,它的任务是在 PHP 脚本的不同执行之间传递消息。是的,这需要 shell 访问。所有 PHP 执行都将通过套接字连接到该服务器组件,并且可以传递消息。做对很棘手,但最后效果很好。

不幸的是,comet 请求可能非常浪费内存和 CPU 周期。我的 Apache 服务器有一个基于 PHP 的进程执行模型。因此,当聊天中有 100 人时,这意味着随时有 100 个待处理的彗星请求,这意味着有 100 个 Apache 进程在运行。即使一个新的 Apache 进程只使用 10MB,也就是总共 1GB!那是很多内存,而这些过程只不过是在等待某些事情发生。聊天是一个令人难以置信的记忆猪。此外,这样的聊天确实会产生很多请求:每次有人在聊天中说些什么,所有 100 个请求都会返回,然后您将立即收到 100 个新请求。聊天中的用户数量增加两倍通常意味着请求数量增加四倍。你真的希望这很活泼。 Apache 在处理这个问题时并不总是那么有效。周围有一些 Web 服务器软件专门针对彗星请求进行了调整,并且可以很好地扩展,但这又需要比您拥有更多的服务器访问权限。

因此,为了完整起见,我的故事到此结束:与此同时,我放弃了所有 PHP 并完全重写了聊天内容。在我看来,Apache 和 PHP 非常不适合这种任务。现在有一个集成了高效的多线程 HTTP 服务器的 Java 服务器组件。我对它进行了压力测试,它的表现非常好:连接了 500 个垃圾邮件客户端,CPU 使用率不超过 15%,内存使用率保持在 150MB。这比我预期的要好得多。与 Apache/PHP 相比,它的响应能力也提高了很多。最终结果可以在http://www.dark-chat.info/查看,尽管由于各种原因聊天目前有些死。随着我有更多时间,这种情况有望改变。

好吧,我知道这对您没有多大帮助,因为您受到托管服务提供商的严格限制。如果没有 shell 访问权限,你能做的真的只有这么多。如果您可以延迟 2 秒(或延迟 1 秒)并且您不希望同时有超过 20 个用户,那么您真的可以进行轮询。有一些方法可以对此进行一些优化,例如,活跃用户可以获得 1 秒的投票,而那些很少写东西的用户可以获得 5 秒的投票。

也就是说,也许您也可以四处寻找某种托管解决方案。我确定您可以通过 iframe 嵌入聊天。

好的,这比我想要的要长得多。但我希望它可以帮助一些人。 :)

【讨论】:

  • 感谢您的洞察力,刚刚接手了一个需要 IM 和聊天室的项目,您在此处概述的调查结果为我证实了一些事情。精彩的帖子!
【解决方案2】:

在不使用任何插件(Flash、Java 等)的情况下实现聊天的唯一方法是 WebSocket。 (以特定间隔连接服务器以检查新消息是一种实现方式,但我认为它太“脏”了......)但是,我认为 Web 托管站点可能不提供 WebSocket 服务器。我建议您通过使用 Java/Flash 进行连接来创建 IRC 客户端。如果要使用 HTML/JS 制作 UI,请在 Flash 中使用 ExternalInterface 或在 Java 中使用 JSObject 来实现插件和 JS 之间的通信。

【讨论】:

    【解决方案3】:

    我不能说太多,但目前用于此类事情的常用技术是comet
    在 Comet 中,您打开一个对服务器的请求(例如,使用 AJAX 之类的东西),但您没有关闭它。您只需将其保持打开状态,但仅在需要时才将数据从服务器发送到客户端。这项技术还需要一些特殊的服务器,但我认为如果你谷歌一下,你肯定会找到一种用 PHP 实现 Comet 的方法(但我认为 Python 更适合这样的事情)......

    希望这能给你一些想法,如何解决你的问题:)

    【讨论】:

      【解决方案4】:

      HTML 5 有一个很酷的新特性,称为 Web Sockets,它允许客户端和服务器之间真正的双向通信。但是,您不会找到任何便宜的共享托管计划来让您托管自己的 Web Socket 服务器。

      您可以通过“老式”方式来伪造双向通信:使用 AJAX。基本上,客户端 JavaScript 每隔几秒就会向数据库发出一次请求,以检查是否有任何新的聊天消息要显示。发布一条新消息就是将该消息发布到服务器。

      Comet 只是一种花哨的(更高效的服务器端)方法。

      【讨论】:

        【解决方案5】:

        正如许多人所提到的,实现此目的的流行方法是使用 ajax、comet(或其他一些长轮询机制)或 WebSockets。

        我的建议是使用 WebSockets,但正如前面提到的,您的主机可能不允许您设置套接字服务器。

        如果您遇到这种情况,我建议使用Server Sent Events,这是另一种被 WebSockets 所掩盖的 HTML5 解决方案。

        它将允许您向浏览器发送事件,并且仍然可以轻松地在 PHP 中实现。

        【讨论】:

          猜你喜欢
          • 2013-05-28
          • 1970-01-01
          • 2014-09-22
          • 2021-12-02
          • 1970-01-01
          • 2012-05-06
          • 1970-01-01
          • 1970-01-01
          • 2016-01-18
          相关资源
          最近更新 更多