基于HTTP长连接的"服务器推"技术的php 简易聊天室


Posted in PHP onOctober 31, 2009

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

<?php 
//chat.php 
header('cache-control: private'); 
header('Content-Type: text/html; charset=utf-8'); 
?> 
<html> 
<script type="text/javascript"> 
function submitChat(obj) { 
obj.submit(); 
document.getElementsByName('content')[0].value = ''; 
} 
</script> 
<iframe src="./chat_content.php" height="300" width="100%"></iframe> 
<iframe name="say" height="0" width="0"></iframe> 
<form method="POST" target="say" action="./say.php" onsubmit="submitChat(this)"> 
<input type="text" size="30" name="content" /> <input type="button" value="say" onclick="submitChat(this.form)" /> 
</form> 
</html>

另外一个就是保存用户提交的聊天内容了,我简单的写一下文本,而且没有做什么锁定,这个只是简易版本:
<?php 
$content = trim($_POST['content']); 
if ($content) { 
$fp = fopen('./chat.txt', 'a'); 
fwrite($fp, $content . "\n"); 
fclose($fp); 
clearstatcache(); 
} 
?>

接下来看主要的HTTP长连接部分,也就是chat_content.php文件:

<?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 '<div>'; 
echo htmlspecialchars($content); 
echo "</div>"; 
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连接。

OK,基本上原理就是这样了,当然这个性能不清楚,有兴趣的自己试试,欢迎交流。

PHP 相关文章推荐
php str_pad 函数使用详解
Jan 13 PHP
一个典型的PHP分页实例代码分享
Jul 28 PHP
php简单浏览目录内容的实现代码
Jun 07 PHP
php数组操作之键名比较与差集、交集赋值的方法
Nov 10 PHP
PHP获取一年中每个星期的开始和结束日期的方法
Feb 12 PHP
php实现多城市切换特效
Aug 09 PHP
Laravel使用Caching缓存数据减轻数据库查询压力的方法
Mar 15 PHP
php文件上传类完整实例
May 14 PHP
YII框架学习笔记之命名空间、操作响应与视图操作示例
Apr 30 PHP
laravel框架之数据库查出来的对象实现转化为数组
Oct 23 PHP
one.php 多项目、函数库、类库 统一为一个版本的方法
Aug 24 PHP
YII2 全局异常处理深入讲解
Mar 24 PHP
php UTF8 文件的签名问题
Oct 30 #PHP
PHP+MySQL 手工注入语句大全 推荐
Oct 30 #PHP
php 攻击方法之谈php+mysql注射语句构造
Oct 30 #PHP
PHP 文件上传源码分析(RFC1867)
Oct 30 #PHP
浅谈PHP 闭包特性在实际应用中的问题
Oct 30 #PHP
php实现jQuery扩展函数
Oct 30 #PHP
PHP 读取和修改大文件的某行内容的代码
Oct 30 #PHP
You might like
Wordpress 相册插件 NextGEN-Gallery 添加目录将中文转为拼音的解决办法
2010/12/29 PHP
PHP下打开phpMyAdmin出现403错误的问题解决方法
2013/05/23 PHP
深入讲解PHP Session及如何保持其不过期的方法
2015/08/18 PHP
yii2控制器Controller Ajax操作示例
2016/07/23 PHP
thinkPHP5.0框架整体架构总览【应用,模块,MVC,驱动,行为,命名空间等】
2017/03/25 PHP
PHP编程计算日期间隔天数的方法
2017/04/26 PHP
firefox中JS读取XML文件
2006/12/21 Javascript
使用IE6看老赵的博客 jQuery初探
2010/01/17 Javascript
Jquery中Ajax 缓存带来的影响的解决方法
2011/05/19 Javascript
jQuery源码中的chunker 正则过滤符分析
2012/07/31 Javascript
jQuery中is()方法用法实例
2015/01/06 Javascript
js实现tab选项卡切换功能
2017/01/13 Javascript
利用jqprint插件打印页面内容的实现方法
2018/01/09 Javascript
vue实现下载文件流完整前后端代码
2020/11/17 Vue.js
Vue仿Bibibili首页的问题
2021/01/21 Vue.js
python二分法实现实例
2013/11/21 Python
Anaconda多环境多版本python配置操作方法
2017/09/12 Python
DataFrame 将某列数据转为数组的方法
2018/04/13 Python
对python指数、幂数拟合curve_fit详解
2018/12/29 Python
在Python 中同一个类两个函数间变量的调用方法
2019/01/31 Python
python实现点击按钮修改数据的方法
2019/07/17 Python
python @propert装饰器使用方法原理解析
2019/12/25 Python
django的403/404/500错误自定义页面的配置方式
2020/05/21 Python
Python接口测试文件上传实例解析
2020/05/22 Python
python获取天气接口给指定微信好友发天气预报
2020/12/28 Python
Fashion Eyewear美国:英国线上设计师眼镜和太阳镜的零售商
2016/08/15 全球购物
帕克纽约:PARKER NY
2018/12/09 全球购物
马德里著名的运动鞋商店:NOIRFONCE
2019/04/12 全球购物
The North Face北面荷兰官网:美国著名户外品牌
2019/10/16 全球购物
电大学习个人自我评价范文
2013/10/04 职场文书
法制教育演讲稿
2014/09/10 职场文书
领导干部学习“三严三实”思想汇报
2014/09/15 职场文书
2014年标准化工作总结
2014/12/17 职场文书
安全生产标语口号
2015/12/26 职场文书
python用字节处理文件实例讲解
2021/04/13 Python
解析在浏览器地址栏输入一个URL后发生了什么
2021/06/21 Servers