如何使用jQuery、PHP和MySQL实现聊天功能?

4
我使用php,mysql和jquery制作了一个聊天脚本。它使用json从服务器获取数据。它定期向服务器进行请求并发送上一次获取的消息id以获取来自服务器的新消息。但是当多个用户聊天时,每小时会向服务器发出成千上万个请求,并且主机提供商肯定会将其阻止。
我认为Gmail聊天使用socket,因为它肯定不会发送定期请求。请问你们中有人可以给我一些示例代码或指导如何解决这个问题吗?
我急需帮助,非常感谢您的帮助。对您表示敬意和问候。
6个回答

7
如果您使用的主机在处理如此多的请求时“肯定会阻止它”,那么在担心代码之前,您可能需要考虑获取不同的主机或升级您的托管套餐。请查看Facebook如何实现他们的聊天:http://www.facebook.com/note.php?note_id=14218138919 我们选择的将文本从一个用户传输到另一个用户的方法涉及在每个Facebook页面上加载iframe,并使该iframe的Javascript通过持久连接发出HTTP GET请求,直到服务器为客户端提供数据为止。如果请求被中断或超时,则重新建立请求。这绝不是一种新技术:它是Comet的变体,具体来说是XHR长轮询和/或BOSH。

即使我使用iframe进行跨域ajax请求。我的聊天脚本将被安装在其他网站上,但消息和用户列表将存储在我的服务器上。虽然需要了解更多关于持久连接的知识,如果您有空的话,我会非常感激一些提示。谢谢雅虎! - Kunal

1

如果你想了解如何使用Prototype的'comet'守护进程和jetty webserver来实现'comet'技术,那么例子对你很有用。在jetty下载中的示例代码中有一个聊天应用程序的示例。

最近我自己安装了jetty,所以你可能会觉得我的安装命令记录很有用:

开始尝试运行'comet'服务

http://maven.apache.org/下载Maven

使用http://maven.apache.org/download.html#Installation安装Maven 我执行了以下命令 提取到/home/sdwyer/apache-maven-2.0.9

> sdwyer@pluto:~/apache-maven-2.0.9$ export M2_HOME=/home/sdwyer/apache-maven-2.0.9
> sdwyer@pluto:~/apache-maven-2.0.9$ export M2=$M2_HOME/bin
> sdwyer@pluto:~/apache-maven-2.0.9$ export PATH=$M2:$PATH.
> sdwyer@pluto:~/apache-maven-2.0.9$ mvn --version
-bash: /home/sdwyer/apache-maven-2.0.9/bin/mvn: Permission denied

> sdwyer@pluto:~/apache-maven-2.0.9$ cd bin
> sdwyer@pluto:~/apache-maven-2.0.9/bin$ ls
m2 m2.bat m2.conf mvn mvn.bat mvnDebug mvnDebug.bat

> sdwyer@pluto:~/apache-maven-2.0.9/bin$ chmod +x mvn

> sdwyer@pluto:~/apache-maven-2.0.9/bin$ mvn –version

Maven version: 2.0.9
Java version: 1.5.0_08
OS name: “linux” version: “2.6.18-4-686″ arch: “i386″ Family: “unix”
sdwyer@pluto:~/apache-maven-2.0.9/bin$

http://www.mortbay.org/jetty/下载Jetty服务器

解压到/home/sdwyer/jetty-6.1.3

> sdwyer@pluto:~$ cd jetty-6.1.3//examples/cometd-demo

> mvn jetty:run

一整套下载正在运行

完成后,打开浏览器并将其指向:http://localhost:8080 并测试演示。

示例演示的代码可以在目录中找到:

jetty-6.1.3/examples/cometd-demo/src/main/webapp/examples

1

1

对错不论,一个托管公司可能会因为以下几个原因而变得烦躁:

1)很有可能他们正在使用Apache Prefork。每个聊天请求可能都会创建一个新的连接,从而占用一个Apache进程。每个Apache进程占用的内存从1MB到100MB不等。

2)如果他们维护数据库服务器,而你作为客户在数据库编程方面不擅长,那么你可能会给他们的数据库带来压力。所谓“不擅长”可以指任何事情,从“没有正确建立索引”到“执行了大量细小的查询而不是合理的大查询”。

如上所建议,确保你的代码使用持久连接。此外:

1)在客户端实现一个退避算法。在活动期间每秒轮询服务器,然后逐渐增加轮询间隔,比如5秒、10秒、20秒等等。这样当没有活动时就不会给服务器造成过大负担。

2)多个标签页会让你崩溃。用户打开10个标签页,而它们都有你的聊天小部件每秒轮询服务器?这可不妙。即使你的主机不生气,性能也会下降。

如果这个东西变得很大,设计你的系统使得你可以独立运行聊天服务器部分而不影响其他网站应用。换句话说,客户端将会向“chat.yourwebapp.com”发出请求,而这个域名将会在像lighttpd这样的服务器上运行。

非常感谢您的回复。如果您能解释一下第一点,我会非常感激。运行lighttpd有哪些好处?请解释一下。 - Kunal
不同的服务器对于获取消息和用户列表是个好主意。但是如何在不同的服务器之间维护会话呢?我认为 Web 服务可以帮助解决这个问题,你觉得呢? - Kunal
如果您的session_id存储在数据库中,而您的cookie是针对域名顶部(.yourdomain.com而不是www.yourdomain.com)的,则所有服务器都可以共享同一个会话。看看大多数会话处理程序如何运作-跨服务器共享会话并不太难 :-) - Cory R. King
lighttpd基本上是一款不占用太多内存的“苗条”Web服务器。您可以使用FastCGI运行php聊天程序。不过,我认为现在还不必太担心这个问题 - 只需设计您的应用程序,以便您可以将聊天部分“分叉”,使其独立于应用程序的其他部分运行即可。 - Cory R. King

0
你考虑在页面中嵌入一个小的Flash动画,然后使用套接字来处理与服务器的通信。这将减轻服务器的负担,并使保持一切同步变得更加容易。UI仍然可以使用JavaScript制作。
如果你决定继续使用JavaScript解决方案,那么请忽略我的回答 :-)

嘿,这听起来真的很酷。很想尝试一下类似的东西。但问题是我不知道如何使用JS函数控制Flash电影,以及它如何与服务器上的MySQL数据库和PHP代码进行通信 :( 感激您的帮助。谢谢。 - Kunal

0

为什么主机会阻止这个?如果您正在请求一个标准的http页面,如果您的主机不允许这样做,那么就是时候换主机了。

至于使用套接字,JavaScript没有原生连接到套接字的能力,尽管我相信JSocket是一个库,它允许您通过嵌入式Flash桥接套接字,实际上连接到您的服务器。我还没有找到一个可以做到这一点的jQuery插件,可能有一个。

您的服务器端代码也会发生很大变化(持久性与轮询非常不同),所以您需要努力工作。

我建议您继续做您正在做的事情,并升级您的主机,如果它无法处理它。除非您将同时拥有大量用户?如果繁忙时缓存系统可以避免每个请求都命中数据库,可能可以加速。


我该如何在向客户端发送JSON数据的页面中添加缓存?请给予建议。 - Kunal
好的。假设你平均每秒有300个更新请求,这通常会转化为每秒300个数据库查询。相反,你可以拥有一个简单的文件来保存最新的JSON数据,在每个请求中检查文件的最后修改时间,如果超过一秒钟,就访问你的数据库并...(限制) - savageguy
这样我只是减少了对数据库服务器的请求,而不是对Web服务器的请求。即使要检查文件,我也必须定期向Web服务器发出请求。期待您的看法。 - Kunal
现在iframe发送请求到一个检查用户是否已经认证的ph页面。如果是,则只加载聊天页面,该页面又会请求另一个页面的消息,该页面仅返回JSON数据。继续... - Kunal
我使用 Firebug 观察 Gmail 聊天。它不会定期发送消息请求,而是针对鼠标移动、失焦、聚焦等不同事件发送请求...此外,消息会自动显示,无需任何请求...这让我非常惊讶...我不知道他们是如何做到的! - Kunal
显示剩余7条评论

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