如何实现使用jQuery / PHP聊天室? [英] How to implement a chat room using Jquery/PHP?

查看:416
本文介绍了如何实现使用jQuery / PHP聊天室?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在找实现使用PHP / Java脚本(jQuery的)与两个群聊和私聊功能的聊天室。

现在的问题是如何不断地以自然的方式更新界面,可能还怎么显示'X是打字..在私人聊天信息。

最显而易见的方法似乎是每X秒/毫秒的JavaScript坪的服务器,并获取最后一个ping和现在的新邮件列表。然而,这可以使界面显得有点不自然,如果突然聊天室里充斥着5的消息。因为它是类型化的,我宁愿每个消息出现。

有没有办法对JavaScript,以保持与服务器的持续连接,服务器推任何新的消息,就此,和JavaScript将它们添加到界面,使他们同时出现,几乎就当服务器接受到他们?

我知道有一些需要你安装一些Apache模块等一些投票站的选择,但我是一个系统管理员的pretty的不好,所以我倒是preFER,如果有一个非常容易安装的解决方案在一个共享的托管帐户,或PHP / MySQL的唯一解决方案。

解决方案

用PHP / AJAX / JSON聊天

我用这本书/教程写我的聊天应用:

AJAX和PHP:构建响应Web应用程序:第5章:AJAX聊天和JSON

它显示了如何从头开始写一个完整的chatscript。


彗星的聊天

您也可以使用彗星,提供的 PHP

来源:的Zeitoun

彗星使web服务器将数据发送给客户端,而无需任何需要的客户端请求它。为此,这种技术会产生更加适应应用,而不是传统的AJAX。在经典AJAX应用,网络浏览器(客户)可以不被通知,所述服务器数据模型已经改变实际时间。用户必须(通过点击一个链接例如)创建一个请求或者周期性AJAX请求必须以获得新数据来回服务器发生。

我会告诉你两种方法来实现彗星与PHP的方式。例如:

  1. 基于隐< IFRAME> 使用服务器时间戳
  2. 基于经典的AJAX非返回请求

第一实时显示服务器日期上的客户端,显示器迷你聊天。

方法1:IFRAME +服务器时间戳

您需要:

  • 在后端PHP脚本来处理持续的HTTP请求 backend.php
  • 在一个frondend HTML脚本加载的Javascript code index.html的
  • 原型JS库,但你也可以使用jQuery

后端脚本( backend.php )会做一个无限循环,将返回该服务器的时间,只要客户端连接。

 < PHP
标题(缓存控制:无缓存,必重新验证);
标题(截止日期:太阳,2012年3月5日05:00:00 GMT);
冲洗();
?>

!< D​​OCTYPE HTML PUBLIC -  // W3C // DTD XHTML 1.1 // ENhttp://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
< HTML的xmlns =htt​​p://www.w3.org/1999/xhtml>

< HEAD>
    <冠军>彗星PHP后台< /标题>
    < META HTTP-当量=Content-Type的CONTENT =text / html的;字符集= UTF-8/>
< /头>

<身体GT;
<脚本类型=文/ JavaScript的>
// KHTML的浏览器不共享内置页框的JavaScript代码
VAR is_khtml = navigator.appName.match(Konqueror的)|| navigator.appVersion.match(KHTML);
如果(is_khtml)
{
  VAR prototypejs = document.createElement方法(脚本);
  prototypejs.setAttribute(类型,文/ JavaScript的);
  prototypejs.setAttribute('的src','的prototype.js');
  VAR头= document.getElementsByTagName('头');
  头[0] .appendChild(prototypejs);
}
//将彗星对象
VAR彗星= window.parent.comet;
< / SCRIPT>

< PHP
而(1){
    回声'<脚本类型=文/ JavaScript的>';
    回声comet.printServerTime(的时间()。');';
    回声'< / SCRIPT>';
    冲洗(); //用于将回波数据发送到客户端
    睡眠(1); //稍微休息一下卸载服务器CPU
}
?>
< /身体GT;
< / HTML>
 

前端脚本( index.html的)创建了一个彗星的JavaScript对象,将后端脚本连接到时间容器标签。

 <!DOCTYPE HTML PUBLIC -  // W3C // DTD XHTML 1.1 // ENhttp://www.w3.org/TR/xhtml11/DTD/xhtml11 .dtd>
< HTML的xmlns =htt​​p://www.w3.org/1999/xhtml>
< HEAD>
  <冠军>彗星演示< /标题>
  < META HTTP-当量=Content-Type的CONTENT =text / html的;字符集= UTF-8/>
  <脚本类型=文/ JavaScript的SRC =的prototype.js>< / SCRIPT>

< /头>
<身体GT;
  < D​​IV ID =内容>在服务器的时间都会在这里显示&LT进行; / DIV>

<脚本类型=文/ JavaScript的>
VAR彗星= {
连接:假的,
iframediv:假的,

初始化:函数(){
  如果(navigator.appVersion.indexOf(MSIE)!=  -  1){

    //对于IE浏览器
    comet.connection =新的ActiveXObject(HTMLFILE);
    comet.connection.open();
    comet.connection.write(< HTML>中);
    comet.connection.write(<脚本>的document.domain ='+ document.domain的+');
    comet.connection.write(< / HTML>中);
    comet.connection.close();
    comet.iframediv = comet.connection.createElement(分区);
    comet.connection.appendChild(comet.iframediv);
    comet.connection.parentWindow.comet =彗星;
    comet.iframediv.innerHTML =< IFRAME ID ='comet_iframe'SRC =&GT'/ backend.php。';< / IFRAME>中;

  }否则如果(navigator.appVersion.indexOf(KHTML)!=  -  1){

    //为KHTML浏览器
    comet.connection = document.createElement方法(IFRAME);
    comet.connection.setAttribute('身份证','comet_iframe');
    comet.connection.setAttribute('的src','./backend.php');
    与(comet.connection.style){
      位置=绝对;
      左=顶部=-100px;
      高度=宽度=1px的;
      能见度=隐藏;
    }
    document.body.appendChild(comet.connection);

  } 其他 {

    //对于其他浏览器(Firefox ...)
    comet.connection = document.createElement方法(IFRAME);
    comet.connection.setAttribute('身份证','comet_iframe');
    与(comet.connection.style){
      左=顶部=-100px;
      高度=宽度=1px的;
      能见度=隐藏;
      显示=无;
    }
    comet.iframediv = document.createElement方法(IFRAME);
    comet.iframediv.setAttribute('的src','./backend.php');
    comet.connection.appendChild(comet.iframediv);
    document.body.appendChild(comet.connection);

  }
},

//这个函数会从backend.php称为
printServerTime:函数(时间){
  $(内容)的innerHTML =时间;
},

onUnload:函数(){
  如果(comet.connection){
    comet.connection = FALSE; //重新加载页面时释放的iframe,以prevent问题与IE浏览器
  }
}
}
Event.observe(窗口,载,comet.initialize);
Event.observe(窗口,卸载,comet.onUnload);

< / SCRIPT>

< /身体GT;
< / HTML>
 

方法2:AJAX无返回的请求

您需要的相同的方法1 +的数据交换文件(<$ C C $>的data.txt )

现在,backend.php会做两件事情:

  1. 写为data.txt中当有新邮件发送
  2. 请一个无限循环,只要的data.txt的文件是不变的

 &LT; PHP
$文件名=目录名(__ FILE __)'/ data.txt中。

//在文件中存储新信息
$味精=使用isset($ _ GET ['味精'])? $ _GET ['味精']:'';
如果($味精!='')
{
    file_put_contents($文件名,$味精);
    死();
}

//无限循环,直到数据文件没有被修改
$ lastmodif =使用isset($ _ GET ['戳'])?
 

     

$ _ GET ['戳']:0;       $ currentmodif = filemtime($文件名);       而($ currentmodif&LT; = $ lastmodif)//检查数据文件   已被修改       {           usleep(10000); //睡眠10ms的卸载CPU           clearstatcache()函数;           $ currentmodif = filemtime($文件名);       }

  //返回一个JSON数组
$响应=阵列();
$响应['味精'] =的file_get_contents($文件名);
$响应['时间戳'] = $ currentmodif;
回声json_en code($响应);
冲洗();
?&GT;
 

前端脚本( index.html的)创建&LT; D​​IV ID =内容&GT;&LT; / DIV&GT; 标签的帽子会包含聊天消息正在添加的的data.txt的文件,最后它创建一个彗星的JavaScript对象,将调用为了看新的聊天消息的后台脚本。

彗星对象将发送Ajax请求已收到新的消息,每次每一次新的消息发布。持久连接只用于监视新邮件。时间戳url参数用于识别上一个请求消息,使得服务器将返回仅当data.txt中时间戳是较新的,客户端的时间戳。

 &LT;!DOCTYPE HTML PUBLIC -  // W3C // DTD XHTML 1.1 // ENhttp://www.w3.org/TR/xhtml11/DTD/xhtml11 .dtd&GT;
&LT; HTML的xmlns =htt​​p://www.w3.org/1999/xhtml&GT;
&LT; HEAD&GT;
  &LT;冠军&GT;彗星演示&LT; /标题&GT;

  &LT; META HTTP-当量=Content-Type的CONTENT =text / html的;字符集= UTF-8/&GT;
  &LT;脚本类型=文/ JavaScript的SRC =的prototype.js&GT;&LT; / SCRIPT&GT;
&LT; /头&GT;
&LT;身体GT;

&LT; D​​IV ID =内容&GT;
&LT; / DIV&GT;

&其中p为H.;
&LT;形式的行动=的方法=获取的onsubmit =comet.doRequest($('字')值。); $('字')值='';返回false;&GT;
  &LT;输入类型=文本名称=字ID =字值=/&GT;
  &LT;输入类型=提交名称=提交值=发送/&GT;
&LT; /形式GT;
&所述; / P&GT;

&LT;脚本类型=文/ JavaScript的&GT;
变种彗星= Class.create();
Comet.prototype = {

时间戳:0,
网址:./backend.php,
NOERROR:真正的,

初始化:功能(){},

连接:函数()
{
  this.ajax =新的Ajax.Request(this.url,{
    方法:'得到',
    参数:{时间戳:this.timestamp},
    的onSuccess:函数(运输){
      //处理服务器响应
      变种响应= transport.responseText.evalJSON();
      this.comet.timestamp =响应['戳'];
      this.comet.handleResponse(响应);
      this.comet.noerror = TRUE;
    },
    的onComplete:函数(运输){
      //当这个请求完成后发送一个新的Ajax请求
      如果(!this.comet.noerror)
        //如果出现连接问题,请尝试重新连接每5秒一个
        的setTimeout(函数(){comet.connect()},5000);
      其他
        this.comet.connect();
      this.comet.noerror = FALSE;
    }
  });
  this.ajax.comet =这一点;
},

断开:函数()
{
},

用handleResponse:函数(响应)
{
  $(内容)的innerHTML + ='&LT; D​​IV&GT; +响应['味精'] +'&LT; / DIV&GT;';
},

doRequest:函数(要求)
{
  新的Ajax.Request(this.url,{
    方法:'得到',
    参数:{味精:要求
  });
}
}
VAR彗星=新彗星();
comet.connect();
&LT; / SCRIPT&GT;

&LT; /身体GT;
&LT; / HTML&GT;
 


或者

您也可以看看其他的聊天应用程序,看看他们是如何做的:

I'm looking to implement a chat room using PHP/Javascript (Jquery) with both group chat and private chat features.

The problem is how to continually update the interface in a natural way and possibly also how to show 'X is typing..' messages in private chat.

The obvious way seems to be that every X seconds/milliseconds the javascript pings the server and fetches a list of new messages between the last ping and now. However, this can make the interface seem a bit unnatural, if suddenly the chat room is flooded with 5 messages. I would rather each message appear as it is typed.

Is there a way for javascript to maintain a continuous connection to the server, the server pushes any new messages to this connection, and javascript adds them to the interface so they appear simultaneously, almost as soon as the server receives them?

I know there are some polling options that require you to install some apache modules etc, but I'm pretty bad of a sysadmin, therefore I'd prefer if there was a very easy to install solution on a shared hosting account, or a php/mysql only solution.

解决方案

Chat with PHP/AJAX/JSON

I used this book/tutorial to write my chat application:

AJAX and PHP: Building Responsive Web Applications: Chapter 5: AJAX chat and JSON.

It shows how to write a complete chatscript from scratch.


Comet based chat

You can also use Comet with PHP.

From: zeitoun:

Comet enables web servers to send data to the client without having any need for the client to request it. Therefor, this technique will produce more responsive applications than classic AJAX. In classic AJAX applications, web browser (client) cannot be notified in real time that the server data model has changed. The user must create a request (for example by clicking on a link) or a periodic AJAX request must happen in order to get new data fro the server.

I'll show you two ways to implement Comet with PHP. For example:

  1. based on hidden <iframe> using server timestamp
  2. based on a classic AJAX non-returning request

The first shows the server date in real time on the clients, the displays a mini-chat.

Method 1: iframe + server timestamp

You need:

  • a backend PHP script to handle the persistent http request backend.php
  • a frondend HTML script load Javascript code index.html
  • the prototype JS library, but you can also use jQuery

The backend script (backend.php) will do an infinite loop and will return the server time as long as the client is connected.

<?php
header("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 iframes
var 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 object
var comet = window.parent.comet;
</script>

<?php
while(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>

The frontend script (index.html) creates a "comet" javascript object that will connect the backend script to the time container tag.

<!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='./backend.php'></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',    './backend.php');
    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', './backend.php');
    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>

Method 2: AJAX non-returning request

You need the same as in method 1 + a file for dataexchange (data.txt)

Now, backend.php will do 2 things:

  1. Write into "data.txt" when new messages are sent
  2. Do an infinite loop as long as "data.txt" file is unchanged

<?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 been modified { 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_encode($response);
flush();
?>

The frontend script (index.html) creates the <div id="content"></div> tags hat will contains the chat messages comming from "data.txt" file, and finally it create a "comet" javascript object that will call the backend script in order to watch for new chat messages.

The comet object will send AJAX requests each time a new message has been received and each time a new message is posted. The persistent connection is only used to watch for new messages. A timestamp url parameter is used to identify the last requested message, so that the server will return only when the "data.txt" timestamp is newer that the client timestamp.

<!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: './backend.php',
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>


Alternatively

You can also have a look at other chat applications to see how they did it:

这篇关于如何实现使用jQuery / PHP聊天室?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆