PHP服务器器推,php服务器推技术的聊天室

演示例子1,

首先是首页,包含一个文本输入和一个显示聊天内容的iframe,还有一个隐藏iframe用来提交form表单:

复制代码 代码示例:

//chat.php

header('cache-control: private');

header('Content-Type: text/html; charset=utf-8');

?>

function submitChat(obj) {

obj.submit();

document.getElementsByName('content')[0].value = '';

}

保存用户提交的聊天内容

简易版本:

复制代码 代码示例:

$content = trim($_POST['content']);

if ($content) {

$fp = fopen('./chat.txt', 'a');

fwrite($fp, $content . "\n");

fclose($fp);

clearstatcache();

}

?>

主要的HTTP长连接部分,chat_content.php文件:

复制代码 代码示例:

header('cache-control: private');

header('Content-Type: text/html; charset=utf-8');

//测试设置30秒超时,一般会设置比较长时间。

set_time_limit(30);

//这一行是为了搞定IE这个BT

echo str_repeat(' ', 256);

ob_flush();

flush();

$fp = new SplFileObject('./chat.txt', 'r+');

$line = 0;

$totalLine = 0;

while (!$fp->eof()) {

$fp->current();

$totalLine++;

$fp->next();

}

$fp->seek($totalLine);

$i = $totalLine - 1;

while (true) {

if (!$fp->eof()) {

if ($content = trim($fp->current())) {

echo '

';

echo htmlspecialchars($content);

echo "

";

flush();

$fp->next();

$i++;

}

} else {

$fp->seek($i - 1);

$fp->next();

}

{

//这里可以添加心跳检测后退出循环

}

usleep(1000);

}

?>

代码说明:

06. 设置一个超时时间,由于要保持HTTP长连接,这个时间肯定要比较长,可能要几个小时吧,上面提到的文章里也有说明,这种HTTP长连接只能打开两个,由于浏览器的限制。另外

其实即使你设置了一个永不超时,其实上服务器部分(如Apache)的配置文件也可能对HTTP请求设置了最长等待时间,所以也可能效果会不是你想的,一般默认可能都是15分钟超时。如果

有兴趣可以自己尝试修改。

09. 这里输出了一段空白,主要是手册上已经说明了,IE浏览器在前面256个字符是不会直接输出的,所以我们先随便输出些空白,以便让后面的内容输出来,可能其他浏览器也有其他

浏览器的设置,具体可以查看PHP手册的frush函数的说明。接下去11、12行就是强制把这些空白符丢给浏览器输出。

13. ~ 20. 这里主要是为了计算文件行数,以便从这一行后面开始读内容。

接下去的while循环就是一个死循环了,就是循环输出文件内容,每次判断是否到达文件末尾,如果有用户写入文件,则当前检测肯定不是文件末尾,就将该行读取出来输出,否则将指

针往前移动一行,继续循环,每次等待1000微秒,

39. 如果一直保持长连接,那么即使客户端断开,服务端也不一定能知道客户端已经断开,所以这里可能还需要做一些心跳记录,比如每个用户保持一个心跳flag,每格几秒更新一下

最后心跳时间,当检测最后时间很久没更新后,推出这个死循环,关闭这个HTTP连接。

演示示例2:

传统的B/S结构的应用程序,都是采用\"客户端拉\"结束来实现客户端和服务器端的数据交换。

本文将通过结合Ticks,来实现一个服务器推的PHP聊天室简单构想。

PHPer,尤其是用过set_cookie, header的,一定见过这样的提示信息:\"Warning: Cannot modify header information - headers already sent by.....\", 这是因为通过HTTP协议通信

,数据包会包含俩个部分,一个是Header,一个是data。

一般来说,都是先Header部分,在Heaer部分指明了Data部分的长度,然后使用\\r\\n\\r\\n来表示header部分结束,接下来是Data部分。

当有任何输出时,Header部分就发送了,此时,再想header函数来改变一些Header部分的域信息,就会得到上面的提示信息。

一个简单的办法就是使用output_buffering。让它来缓存服务器的输出,不要太早将Header部分发给客户端。

那么,如果不使用output_buffering,是不是就可以实现,每当服务器有输出,就立即发送给客户端呢?

做个如下试验:

复制代码 代码示例:

//设置php.ini中output_buffering=0 或者使用ob_end_flush()关闭缓存

set_time_limit(0);

for($i=0;$i<10;$i++){

echo \"Now Index is :\". $i;

sleep(1);

}

?>

结果发现,还是要等到脚本全部执行完以后,才能一次看到所有的结果。为什么呢?

这是因为只是解决了缓存问题,但是还有一个缓冲问题,PHP会缓冲程序的输出。

所以,此时还需要调用,flush(), 来强制使得PHP将所有的程序输出发送给客户端。

复制代码 代码示例:

//设置php.ini中output_buffering=0

ob_end_flush();//关闭缓存

set_time_limit(0);

for($i=0;$i<10;$i++){

echo \"Now Index is :\". $i;

flush();

sleep(1);

}

?>

现在是不是看到了,不断有服务器的数据显示出来?

有几个概念之间的关系,这里补充下:

在代码中使用ob_start(), 就相当于在php.ini中使用output_buffering=on一样,使用服务器缓存。

在代码中使用ob_end_flush() 就相当于在php.ini中使用output_buffering = false一样,关闭服务器缓存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值