与PHP / AJAX / JSON聊天
我使用了这本书/教程来编写我的聊天应用程序:
AJAX和PHP:构建响应式Web应用程序:第5章:AJAX聊天和JSON。
它显示了如何从头开始编写完整的聊天脚本。
基于彗星的聊天
您还可以将
Comet与PHP结合使用。
来自:zeitoun:
Comet使Web服务器可以将数据发送到客户端,而无需客户端请求。因此,与传统的AJAX相比,该技术将产生更多的响应应用程序。在经典的AJAX应用程序中,无法实时通知Web浏览器(客户端)服务器数据模型已更改。用户必须创建一个请求(例如,通过单击链接),或者必须进行定期的AJAX请求,才能从服务器获取新数据。
我将向您展示两种使用PHP实现Comet的方法。例如:
- 基于隐藏
<iframe>
使用服务器时间戳 - 基于经典的AJAX不返回请求
第一个在客户端实时显示服务器日期,并显示一个迷你聊天窗口。
方法1:iframe +服务器时间戳
你需要:
- 后端PHP脚本来处理持久性HTTP请求
backend.php
- 叶状HTML脚本加载Javascript代码
index.html
- 该原型JS库,但你也可以使用jQuery
后端脚本(
backend.php)将进行无限循环,并且只要连接了客户端,就会返回服务器时间。
<?phpheader("Cache-Control: no-cache, must-revalidate");header("Expires: Sun, 5 Mar 2012 05:00:00 GMT");flush();?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>Comet php backend</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><script type="text/javascript">// KHTML browser don't share javascripts between iframesvar is_khtml = navigator.appName.match("Konqueror") || navigator.appVersion.match("KHTML");if (is_khtml){ var prototypejs = document.createElement('script'); prototypejs.setAttribute('type','text/javascript'); prototypejs.setAttribute('src','prototype.js'); var head = document.getElementsByTagName('head'); head[0].appendChild(prototypejs);}// load the comet objectvar comet = window.parent.comet;</script><?phpwhile(1) { echo '<script type="text/javascript">'; echo 'comet.printServerTime('.time().');'; echo '</script>'; flush(); // used to send the echoed data to the client sleep(1); // a little break to unload the server CPU}?></body></html>前端脚本(
index.html)创建一个“comet”javascript对象,该对象将把后端脚本连接到时间容器标签。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>Comet demo</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="prototype.js"></script></head><body> <div id="content">The server time will be shown here</div><script type="text/javascript">var comet = {connection : false,iframediv : false,initialize: function() { if (navigator.appVersion.indexOf("MSIE") != -1) { // For IE browsers comet.connection = new ActiveXObject("htmlfile"); comet.connection.open(); comet.connection.write("<html>"); comet.connection.write("<script>document.domain = '"+document.domain+"'"); comet.connection.write("</html>"); comet.connection.close(); comet.iframediv = comet.connection.createElement("div"); comet.connection.appendChild(comet.iframediv); comet.connection.parentWindow.comet = comet; comet.iframediv.innerHTML = "<iframe id='comet_iframe' src='https://www.mshxw.com/skin/sinaskin/image/nopic.gif'></iframe>"; } else if (navigator.appVersion.indexOf("KHTML") != -1) { // for KHTML browsers comet.connection = document.createElement('iframe'); comet.connection.setAttribute('id', 'comet_iframe'); comet.connection.setAttribute('src', 'https://www.mshxw.com/skin/sinaskin/image/nopic.gif'); with (comet.connection.style) { position = "absolute"; left = top = "-100px"; height = width = "1px"; visibility = "hidden"; } document.body.appendChild(comet.connection); } else { // For other browser (Firefox...) comet.connection = document.createElement('iframe'); comet.connection.setAttribute('id', 'comet_iframe'); with (comet.connection.style) { left = top = "-100px"; height = width = "1px"; visibility = "hidden"; display = 'none'; } comet.iframediv = document.createElement('iframe'); comet.iframediv.setAttribute('src', 'https://www.mshxw.com/skin/sinaskin/image/nopic.gif'); comet.connection.appendChild(comet.iframediv); document.body.appendChild(comet.connection); }},// this function will be called from backend.php printServerTime: function (time) { $('content').innerHTML = time;},onUnload: function() { if (comet.connection) { comet.connection = false; // release the iframe to prevent problems with IE when reloading the page }}}Event.observe(window, "load", comet.initialize);Event.observe(window, "unload", comet.onUnload);</script></body></html>方法2:AJAX不返回请求
您需要使用与方法1相同的方法+一个用于dataexchange的文件(
data.txt)
现在,backend.php将做两件事:
- 发送新消息时写入“ data.txt”
- 只要“ data.txt”文件未更改,就执行无限循环
<?php$filename = dirname(__FILE__).'/data.txt';// store new message in the file$msg = isset($_GET['msg']) ? $_GET['msg'] : '';if ($msg != ''){ file_put_contents($filename,$msg); die();}// infinite loop until the data file is not modified$lastmodif = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;$currentmodif = filemtime($filename);while ($currentmodif <= $lastmodif) // check if the data file has beenmodified
{
usleep(10000); // sleep 10ms to unload the CPU
clearstatcache();
$currentmodif = filemtime($filename);
}// return a json array$response = array();$response['msg'] = file_get_contents($filename);$response['timestamp'] = $currentmodif;echo json_enpre($response);flush();?>
前端脚本(
index.html)创建
<div id="content"></div>标签hat,其中将包含来自“
data.txt”文件的聊天消息,最后,它创建一个“ comet” javascript对象,该对象将调用后端脚本以监视新的聊天消息。
每当接收到新消息以及每次发布新消息时,彗星对象都会发送AJAX请求。持久连接仅用于监视新消息。timestampurl参数用于标识最后请求的消息,以便服务器仅在“ data.txt”时间戳比客户端时间戳新时才返回。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>Comet demo</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="prototype.js"></script></head><body><div id="content"></div><p><form action="" method="get" onsubmit="comet.doRequest($('word').value);$('word').value='';return false;"> <input type="text" name="word" id="word" value="" /> <input type="submit" name="submit" value="Send" /></form></p><script type="text/javascript">var Comet = Class.create();Comet.prototype = {timestamp: 0,url: 'https://www.mshxw.com/skin/sinaskin/image/nopic.gif',noerror: true,initialize: function() { },connect: function(){ this.ajax = new Ajax.Request(this.url, { method: 'get', parameters: { 'timestamp' : this.timestamp }, onSuccess: function(transport) { // handle the server response var response = transport.responseText.evalJSON(); this.comet.timestamp = response['timestamp']; this.comet.handleResponse(response); this.comet.noerror = true; }, onComplete: function(transport) { // send a new ajax request when this request is finished if (!this.comet.noerror) // if a connection problem occurs, try to reconnect each 5 seconds setTimeout(function(){ comet.connect() }, 5000); else this.comet.connect(); this.comet.noerror = false; } }); this.ajax.comet = this;},disconnect: function(){},handleResponse: function(response){ $('content').innerHTML += '<div>' + response['msg'] + '</div>';},doRequest: function(request){ new Ajax.Request(this.url, { method: 'get', parameters: { 'msg' : request });}}var comet = new Comet();comet.connect();</script></body></html>或者
您还可以查看其他聊天应用程序,看看它们是如何做到的:
http://hot-things.net/?q=blite-BlaB!Lite是基于AJAX的,可以在支持MySQL,SQLite和PostgreSQL数据库的任何浏览器聊天系统中获得最佳查看。
Gmail / Facebook样式jQuery聊天 -此jQuery聊天模块使您可以将Gmail / Facebook样式的聊天无缝集成到现有网站中。
编写Javascript / PHP聊天服务器 -教程
CometChat -CometChat在标准共享服务器上运行。只需要PHP + mySQL。



