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

 更新时间:2009年10月31日 00:19:16   作者:  
关于HTTP长连接的“服务器推”技术原理可以查看IBM的这篇文章,我简单的做了个DEMO.
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

首先是首页,包含一个文本输入和一个显示聊天内容的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="http://9i0i.com/pic.php?p=./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,基本上原理就是这样了,当然这个性能不清楚,有兴趣的自己试试,欢迎交流。

相关文章

  • ThinkPHP5.1表单令牌Token失效问题的解决

    ThinkPHP5.1表单令牌Token失效问题的解决

    这篇文章主要给大家介绍了关于ThinkPHP5.1表单令牌Token失效问题的解决方法,文中通过示例代码介绍的非常详细,对大家学习或者使用ThinkPHP具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • 百度地图API使用方法详解

    百度地图API使用方法详解

    百度地图api是由javascript语言编写的,在使用之前需要把api引用到页面中,本篇文章给大家介绍百度地图api使用方法,需要的朋友可以参考下
    2015-08-08
  • Laravel中七个非常有用但很少人知道的Carbon方法

    Laravel中七个非常有用但很少人知道的Carbon方法

    在编写PHP应用时经常需要处理日期和时间,Carbon继承自 PHP DateTime 类的 API 扩展,它使得处理日期和时间更加简单,这篇文章主要给大家分享了Laravel中七个非常有用但很少人知道的Carbon方法,需要的朋友可以参考下。
    2017-09-09
  • 搜索附近的人PHP实现代码

    搜索附近的人PHP实现代码

    这篇文章主要为大家详细介绍了搜索附近的人PHP实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • Yii 2.0自带的验证码使用经验分享

    Yii 2.0自带的验证码使用经验分享

    这篇文章主要给大家介绍了关于使用Yii 2.0自带验证码的一些经验,方便新手们快速上手,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-06-06
  • 通过curl模拟post和get方式提交的表单类

    通过curl模拟post和get方式提交的表单类

    写了个简单的脚本通过curl的方式模拟表单提交。可以通过数组和字符串两种方式提交数据,需要的朋友可以参考下
    2014-04-04
  • php不使用插件导出excel的简单方法

    php不使用插件导出excel的简单方法

    这篇文章主要介绍了php不使用插件导出excel的简单方法,首先获取需要导出的数据的数组,数组的格式在下面。之后就是定义文件名称和需要导出的excel的样式,最后就是循环数组,输出数据了
    2014-03-03
  • 使用PHP如何实现高效安全的ftp服务器(一)

    使用PHP如何实现高效安全的ftp服务器(一)

    FTP服务器(File Transfer Protocol Server)是在互联网上提供文件存储和访问服务的计算机,它们依照FTP协议提供服务,本文给大家介绍使用PHP如何实现高效安全的ftp服务器(一),对php ftp服务器相关知识感兴趣的朋友一起学习吧
    2015-12-12
  • symfony3.4中根据角色不同跳转不同页面功能

    symfony3.4中根据角色不同跳转不同页面功能

    这篇文章主要介绍了symfony3.4中根据角色不同跳转不同页面,在Symfony?3.4中,可以使用安全组件来实现控制不同角色跳转到不同页面的功能,本文通过示例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • Yii2创建表单(ActiveForm)方法详解

    Yii2创建表单(ActiveForm)方法详解

    这篇文章主要介绍了Yii2创建表单(ActiveForm)的方法,结合实例形式详细分析了Yii创建表单的详细步骤及相关函数与属性的使用技巧,需要的朋友可以参考下
    2016-07-07

最新评论

?


http://www.vxiaotou.com