基于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 相关文章推荐
在数据量大(超过10万)的情况下
Jan 15 PHP
用PHP的ob_start();控制您的浏览器cache!
Feb 14 PHP
php中比较简单的导入phpmyadmin生成的sql文件的方法
Jun 28 PHP
比较简单实用的PHP无限分类源码分享(思路不错)
Oct 13 PHP
Php header()函数语法及使用代码
Nov 04 PHP
MongoDB在PHP中的常用操作小结
Feb 20 PHP
PHP使用GIFEncoder类生成gif动态滚动字幕
Jul 01 PHP
thinkphp数据查询和遍历数组实例
Nov 28 PHP
详解PHP数据压缩、加解密(pack, unpack)
Dec 17 PHP
Laravel中log无法写入问题的解决
Jun 17 PHP
ThinkPHP实现登录退出功能
Jun 29 PHP
PHP正则判断一个变量是否为正整数的方法
Feb 27 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设计模式 DAO(数据访问对象模式)
2011/06/26 PHP
PHP 数组和字符串互相转换实现方法
2013/03/26 PHP
PHP实现的解汉诺塔问题算法示例
2018/08/06 PHP
弹出广告特效代码(一个IP只弹出一次)
2007/05/11 Javascript
解决json日期格式问题的3种方法
2014/02/02 Javascript
jQuery中的jQuery()方法用法分析
2014/12/27 Javascript
DOM 高级编程
2015/05/06 Javascript
讲解JavaScript中for...in语句的使用方法
2015/06/03 Javascript
JS实现自动轮播图效果(自适应屏幕宽度+手机触屏滑动)
2017/06/19 Javascript
JS实现按钮添加背景音乐示例代码
2017/10/17 Javascript
详解vue.js之props传递参数
2017/12/12 Javascript
JS交互点击WKWebView中的图片实现预览效果
2018/01/05 Javascript
浅谈用Webpack路径压缩图片上传尺寸获取的问题
2018/02/22 Javascript
微信小程序开发之改变data中数组或对象的某一属性值
2018/07/05 Javascript
angular2/ionic2 实现搜索结果中的搜索关键字高亮的示例
2018/08/17 Javascript
每周一练 之 数据结构与算法(Stack)
2019/04/16 Javascript
Vue-cli3多页面配置详解
2020/03/22 Javascript
[04:13]2014DOTA2国际邀请赛 专访DC目前形势不容乐观
2014/07/12 DOTA
[03:04]2018年国际邀请赛典藏宝瓶&莱恩声望物品展示 片尾有彩蛋
2018/06/04 DOTA
对django 模型 unique together的示例讲解
2019/08/06 Python
Django中ajax发送post请求 报403错误CSRF验证失败解决方案
2019/08/13 Python
基于Python新建用户并产生随机密码过程解析
2019/10/08 Python
OpenCV模板匹配matchTemplate的实现
2019/10/18 Python
西班牙电子产品购物网站:Electronicamente
2018/07/26 全球购物
StubHub新西兰:购买和出售你的门票
2019/04/22 全球购物
俄罗斯极限运动网上商店:Board Shop №1
2020/12/18 全球购物
《记承天寺夜游》教学反思
2014/02/16 职场文书
教师演讲稿大全
2014/05/16 职场文书
食品安全承诺书
2014/05/22 职场文书
数学教师求职信范文
2015/03/20 职场文书
2015年检验科工作总结
2015/04/27 职场文书
开学典礼校长致辞
2015/07/29 职场文书
2016年习总书记讲话学习心得体会
2016/01/20 职场文书
餐厅如何利用“营销策略”扭转亏本局面
2019/10/15 职场文书
在Django中使用MQTT的方法
2021/05/10 Python
详解SpringBoot异常处理流程及原理
2021/06/21 Java/Android