基于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学习 计数器实例代码
Jun 15 PHP
PHP--用万网的接口实现域名查询功能
Dec 13 PHP
PHP 简易输出CSV表格文件的方法详解
Jun 20 PHP
codeigniter集成ucenter1.6双向通信的解决办法
Jun 12 PHP
PHP中使用localhost连接Mysql不成功的解决方法
Aug 20 PHP
php利用smtp类实现电子邮件发送
Oct 30 PHP
Symfony模板的快捷变量用法实例
Mar 17 PHP
php实现遍历文件夹的方法汇总
Mar 02 PHP
php strftime函数获取日期时间(switch用法)
May 16 PHP
yii2.0框架场景的简单使用示例
Jan 25 PHP
phpQuery采集网页实现代码实例
Apr 02 PHP
PHP大文件分割分片上传实现代码
Dec 09 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
YB217、YB235、YB400浅听
2021/03/02 无线电
js+php实现静态页面实时调用用户登陆状态的方法
2015/01/04 PHP
windows8.1下Apache+Php+MySQL配置步骤
2015/10/30 PHP
Extjs EditorGridPanel中ComboBox列的显示问题
2011/07/04 Javascript
seajs中模块的解析规则详解和模块使用总结
2014/03/12 Javascript
$(&quot;&quot;).click与onclick的区别示例介绍
2014/09/25 Javascript
推荐10 个很棒的 jQuery 特效代码
2015/10/04 Javascript
整理关于Bootstrap模态弹出框的慕课笔记
2017/03/29 Javascript
JS中使用正则表达式g模式和非g模式的区别
2017/04/01 Javascript
JS实现图片手风琴效果
2020/04/17 Javascript
jQuery实现锚点向下平滑滚动特效示例
2017/08/29 jQuery
JS中的算法与数据结构之常见排序(Sort)算法详解
2019/08/16 Javascript
浅谈对于“不用setInterval,用setTimeout”的理解
2019/08/28 Javascript
微信小程序tabBar设置实例解析
2019/11/14 Javascript
通过原生vue添加滚动加载更多功能
2019/11/21 Javascript
vue addRoutes路由动态加载操作
2020/08/04 Javascript
[07:26]2015国际邀请赛第二日TOP10集锦
2015/08/06 DOTA
python实现批量获取指定文件夹下的所有文件的厂商信息
2014/09/28 Python
浅析Python多线程下的变量问题
2015/04/28 Python
Python网络爬虫中的同步与异步示例详解
2018/02/03 Python
对python 数据处理中的LabelEncoder 和 OneHotEncoder详解
2018/07/11 Python
python如何发布自已pip项目的方法步骤
2018/10/09 Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
2019/06/26 Python
Python+redis通过限流保护高并发系统
2020/04/15 Python
解决keras模型保存h5文件提示无此目录问题
2020/07/01 Python
三星美国官网:Samsung美国
2017/02/06 全球购物
世界上最大的专业美容用品零售商:Sally Beauty
2017/07/02 全球购物
关键字final的用法
2013/10/02 面试题
毕业生个人的自我评价优秀范文
2013/10/03 职场文书
和解协议书
2014/04/16 职场文书
黄山导游词
2015/01/31 职场文书
遗嘱范文
2015/08/07 职场文书
教师学习中国梦心得体会
2016/01/05 职场文书
《鸡兔同笼》教学反思
2016/02/19 职场文书
使用@Value值注入及配置文件组件扫描
2021/07/09 Java/Android
Python中 range | np.arange | np.linspace三者的区别
2022/03/22 Python