基于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 相关文章推荐
如何做到多笔资料的同步
Oct 09 PHP
PHP Session变量不能传送到下一页的解决方法
Nov 27 PHP
php防攻击代码升级版
Dec 29 PHP
在php中判断一个请求是ajax请求还是普通请求的方法
Jun 28 PHP
根据中文裁减字符串函数的php代码
Dec 03 PHP
PHP遍历并打印指定目录下所有文件实例
Feb 10 PHP
php插入排序法实现数组排序实例
Feb 16 PHP
可兼容php5与php7的cURL文件上传功能实例分析
May 11 PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
May 23 PHP
浅谈Laravel模板实体转义带来的坑
Oct 22 PHP
PHP中关于php.ini参数优化详解
Feb 28 PHP
php的对象传值与引用传值代码实例讲解
Feb 26 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
php 错误处理经验分享
2011/10/11 PHP
php动态添加url查询参数的方法
2015/04/14 PHP
PHP实现文件上传和多文件上传
2015/12/24 PHP
phpmailer简单发送邮件的方法(附phpmailer源码下载)
2016/06/13 PHP
php基于单例模式封装mysql类完整实例
2016/10/18 PHP
PHP有序表查找之二分查找(折半查找)算法示例
2018/02/09 PHP
TP5框架实现签到功能的方法分析
2020/04/05 PHP
使用jQuery.Validate进行客户端验证(初级篇) 不使用微软验证控件的理由
2010/06/28 Javascript
Javascript玩转继承(二)
2014/05/08 Javascript
JavaScript通过setTimeout实时显示当前时间的方法
2015/04/16 Javascript
动态加载js、css的简单实现代码
2016/05/26 Javascript
浅谈react受控组件与非受控组件(小结)
2018/02/09 Javascript
vue 实现全选全不选的示例代码
2018/03/29 Javascript
详解Vue项目引入CreateJS的方法(亲测可用)
2019/05/30 Javascript
用云开发Cloudbase实现小程序多图片内容安全监测的代码详解
2020/06/07 Javascript
python中的字典使用分享
2016/07/31 Python
python3.4下django集成使用xadmin后台的方法
2017/08/15 Python
Python实现随机选择元素功能
2017/09/14 Python
Python3.5内置模块之shelve模块、xml模块、configparser模块、hashlib、hmac模块用法分析
2019/04/27 Python
python实现树的深度优先遍历与广度优先遍历详解
2019/10/26 Python
PyTorch: Softmax多分类实战操作
2020/07/07 Python
Python+pyftpdlib实现局域网文件互传
2020/08/24 Python
了解一下python内建模块collections
2020/09/07 Python
selenium+headless chrome爬虫的实现示例
2021/01/08 Python
Tiqets荷兰:出售欧洲最美丽的景点和博物馆门票
2018/01/09 全球购物
施华洛世奇意大利官网:SWAROVSKI意大利
2018/07/23 全球购物
几道Java和数据库的面试题
2013/05/30 面试题
董事长秘书职责
2014/01/31 职场文书
家长会学生演讲稿
2014/04/26 职场文书
人民调解员培训方案
2014/06/05 职场文书
单位工作证明书格式
2014/10/04 职场文书
班主任高考寄语
2015/02/26 职场文书
民主评议教师党员自我评价
2015/03/04 职场文书
工作感想范文
2015/08/07 职场文书
python实现网络五子棋
2021/04/11 Python
python全面解析接口返回数据
2022/02/12 Python