首页 > 开发 > PHP > 正文

PHP聊天室技术

2024-05-04 23:00:50
字体:
来源:转载
供稿:网友
php聊天室技术
黄国辉

1.前言
  上网聊天是时下最流行的交友方式。各大网站推出的聊天室都各具特色。
  聊天室主要分为webchat、bbschat两种。bbschat是基于telnet的tcp协议,是bbs的附设功能,需要客户端telnet程序。webchat则采用浏览器方式,实际上是一个多人共同使用的cgi程序。其基本原理是把每个用户的发言通过浏览器传给系统,再由系统收集处理后分发给特定用户。
  webchat一般采用server push或client pull技术。两种技术的区别在于使用不同的方式将数据分发给用户,server push是由服务器将数据以多重mime编码,推给(push)使用者端,目前较少网站使用这种方式。client pull则是用户从服务器拉(pull)所要的数据。
  最常用的client pull就是利用html语言的meta标签http-equiv="refresh" 的属性,每隔一段时间就检查服务器上是否有新的数据。例如 ,每隔5秒钟就会刷新一次页面。这种方法简单有效,缺点是刷新时会产生闪烁的现象;而且为了保持效率,每次刷新都会把旧的聊天内容清除,用户想查看或保留对话内容都很不方便。为此,采用javaapplet作为聊天室的前端,利用刷新把从服务器pull的数据通过javaapplet来显示也是一种解决方案。还有就是本文要介绍的使聊天程序保持连线的方案。方法一,把聊天程序设置为无限大,就能使浏览器不停地保持下载的连线状态;方法二,聊天程序中存在着无限循环,因为可以方便地设置更高级的功能,所以在此选择采用。
  web服务器采用freebsd+apache,原因是两者的组合具有最强的性能,而且花费为零。还需要考虑的是用什么方式来存放数据呢。用文件相对而言容易实现,但是多人使用,频繁地对同一文件进行io操作,难免会影响效率,况且freebsd的io性能不佳。可以考虑使用ramdisk,将文件整个放进内存,以提高速度。或者在内存中划分出一块高速空间用以数据存放。笔者使用的是数据库方式:mysql。因为该数据库就是为大批量用户同时使用而设计,利用它可以省去设计高速空间操作的复杂编写,速度也可得到保证。如将整个数据库放进内存,效果更好。
  程序用php+html+javascript编写。聊天室主要是对html的form中的各种元素进行操作。javascript是基于对象的语言,对html中的各种元素皆当作对象看待,所以每个元素的方法和属性都很丰富,操作比较方便。而php只有在form经过post后,将form中的元素转成对应的变量,才能处理用户输入的数据。从交互性来说比较差,这也是使用javascript的原因。采用php的原因是因为比起其它cgi语言,其速度和安全性都较佳,开发也比较容易。
2. 不断刷新的聊天室
  一个标准的聊天室页面由三个frame组成,分别是显示在线用户的online、用户发言及功能设置的say和显示聊天内容的list。用户在say frame中敲入发言内容后按发送,数据经过处理后保存在mysql数据库,同时被保存的还包括发言人、聊天对象及发言的时间。用户一进入聊天室,list frame从mysql数据库中把发言时间大于用户进入时间的发言提出显示出来。而后续显示新的发言内容的关键,在于显示聊天内容的那段程序是无限循环的。
  list frame程序概要:
    $db=mysql_pconnect(localhost,root);    #mysql数据库连接
    mysql_select_db(chat,$db);
    显示欢迎进入聊天室
    设置$init为数据库中发言时间比
      进入时间大的第一个数据的id号   #是数据提取的标志位
    while (1==1) {             #无限循环开始
     提取从$init到最后的数据;
     while (每一个数据$text) {
     $emote=strip_tags($text);        #防止用户直接输入html语言
     if (eregi("^/",$emote))         #判断发言是否系统命令(以/开头)
      系统特殊处理
     else 显示发言
     }
     设置$init为最后数据的id号
     flush();               #清出输出缓冲,使发言马上显示
     sleep(2);               #使程序暂停2秒,节省系统资源
     mysql_free_result($result);       #释放数据库结果占用的内存
    }
  因为程序无限循环,在每次循环中输出的发言是先置入输出缓冲区内。通过flush()马上把缓冲区的内容向用户的list frame送出,达到了实时的聊天效果。循环最后要释放mysql结果集占用的内存,否则因为无限循环的缘故,系统资源很快会被耗尽。
  用户在login后将建立一个online的表用于在线用户的统计,主要是为了防止user表过大,程序中频繁用到的检索会拖慢系统的运作。这其中用的最多的是online frame,在采用client pull的refresh meta,每隔一段时间就会查询online表,以刷新在线的用户。如果用户不发言超过规定时间,系统会调用自定义函数将用户设为timeout,强制将其退出聊天室。
3. 用户功能简介
  用户的功能设置在say frame中,可以选择发言贴图、说话的语气等。发言经过特殊的处理后存储到mysql,例如选择了一个贴图后,系统将添加到发言的前面,就可以实现贴图的效果。
  对于聊天室常用到的emote,例如用户a输入“/hello”按发送,list frame中显示出来的是“用户a愉快地和大家打招呼”,为了保持效率,用户输入的emote会原文直接保存到数据库,而解析转换的工作由list frame来完成。
  悄悄话只有自己和聊天对象可以看到,实现上因为发言预先保存有发言人和聊天对象,只要做一个简单的判断即可。还有聊天室常有的屏蔽某用户发言的功能,通过设置一个临时的阵列来实现,没必要保存在用户的数据库中。
  聊天室人多的时候,大家争先发言常使人眼花缭乱,这时可以选择是否屏蔽无关的发言,即意味着只要不是对所有人和自己的发言将不会显示出来。当然,因为系统会用特殊的颜色来标识和自己有关的发言,就算不选择该功能,用户还是能快速地从众多发言中找到和自己相关的。
  用户可以在特定时间(系统比较空闲时)将当天和自己有关的发言打包。因为存储发言的表数据增长速度很快,为保持运行效率,系统隔天就会把它复制后清空。这样用户检索打包发言内容就不会影响聊天系统的运作。
  出于安全的考虑,聊天室的管理功能是独立的,并没放在聊天页面中。主要有用户资料管理和将捣乱用户kick out(踢人)两种功能。将用户踢出聊天室后将使他在一定的时间内不能再进入聊天室。
  聊天室的安全要求虽然不象电子商务那样高,但如果用户被冒名顶替、用户的发言被窃听,或者乱踢人,是非常令人不快的。用户都要在login中填写名字和密码才能进入聊天室,但是通过查看login的源代码,虽然不能看到php的部分,htnl部分的源码却显示login是调用chat.php程序从而进入聊天室的。所以为了防止用户直接进入聊天室,系统会首先判断新建立的聊天室是否由login产生的,不是则退出。同理,在聊天室的list frame和post frame也可加上这样的防护。当然,在list frame和post frame中检查用户的身份和密码,就万无一失了,只是加重了系统的负担。
  综上所述,能看到系统的源代码无疑是危险的开端,所以系统的编写尽量用看不到源码的php;设置由login开启的聊天室隐藏了浏览器的工具条、状态栏等,并且屏蔽了鼠标的右键及快捷键。
4. 总结
  用php编写的聊天室具有高效稳定的特点,是编写网络交互程序的最佳选择。
参考文献:
[1] rasmus lerdorf著. php manual [m].电子文档,2000


收集最实用的网页特效代码!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表