基于HTTP长连接的"服务器推"技术的php简易聊天室
2023-06-13 09:14:13 时间
首先是首页,包含一个文本输入和一个显示聊天内容的iframe,还有一个隐藏iframe用来提交form表单:
复制代码代码如下:
<?php
//chat.php
header("cache-control:private");
header("Content-Type:text/html;charset=utf-8");
?>
<html>
<scripttype="text/javascript">
functionsubmitChat(obj){
obj.submit();
document.getElementsByName("content")[0].value="";
}
</script>
<iframesrc="./chat_content.php"height="300"width="100%"></iframe>
<iframename="say"height="0"width="0"></iframe>
<formmethod="POST"target="say"action="./say.php"onsubmit="submitChat(this)">
<inputtype="text"size="30"name="content"/><inputtype="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
echostr_repeat("",256);
ob_flush();
flush();
$fp=newSplFileObject("./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>";
echohtmlspecialchars($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连接linux并执行命令,php实现ssh远程连接服务器并操作服务器,PHP跨服务器执行shell脚本
- 数据库PHP究竟如何还原MySQL数据库?(php还原mysql)
- Linux下运行PHP脚本的简单步骤(linux运行php脚本)
- 轻松实现PHP操控MySQL语句(php执行mysql语句)
- 实现缓存PHP开启Redis超越缓存技术(php开启redis)
- PHP如何正确输出MySQL中文字符避免乱码?(php输出mysql乱码)
- 如何在 PHP 中导入 MySQL 数据?(phpmysql导入)
- 利用Redis和PHP实现高效数据处理(redis php 使用)
- PHP无法连接MSSQL服务器(php 读不到mssql)
- PHP如何连接MS SQL服务器(php怎么连接mssql)
- PHP与MSSQL的良好配合,助力数据应用升级(php_mssql)
- 据使用PHP和MSSQL技术记录丰富的数据信息(php mssql记录数)
- PHP简易指南:连接MySQL数据库(php连接mysql数据库)
- 一步一步学习PHP(4)php函数补充2
- PHP安全技术之实现php基本安全
- php中英文语言转换类代码
- php环境配置之CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI比较?
- 有关于PHP中常见数据类型的汇总分享