php实现聊天室功能
原理:长连接
一、长连接与短连接
短连接:客户端与服务端每进行一次报文收发交易时才进行通讯连接、交易完毕后立即断开连接。
长连接:客户端与服务端先建立连接, 连接建立后不断开,然后在进行报文发送和接收。
二、操作过程
短连接的操作步骤是:
建立连接——数据传输——关闭连接——数据传输——关闭连接
长连接的操作步骤是:
建立连接——数据传输……(保持连接)……(数据传输)——关闭连接
三、优缺点
短连接:
常规的短连接模式下,都是通过不间断刷新请求实现的,比如每间隔3秒发送一次Ajax请求,3秒更新一下数据,然后就这样不间断刷新下去,直到用户关闭网页。
弊端:如果用户很长时间都没有操作,每次刷新都不会返回新数据,这样就造成了资源的浪费,很多请求都是没必要的;用户的输入,跟数据的请求不是同步的,会造成一定的信息延迟。
长连接:
Ajax长连接它的刷新是根据数据来执行的,如果有新数据返回,接收并解析显示数据,然后发起新的Ajax请求,如果一段时间内,用户没有操作,则连接出于睡眠状态,一直等待有用户输入或者请求超时,然后发起下个Ajax请求。
好处:每个信息都会即时推送到客户端,延迟极少;每次请求都是有意义的,比短连接效率高很多。
弊端:一个用户量很多,并且操作非常频繁的网站,长连接模式也会出现过于频繁的刷新问题。目前IE对于HTTP连接数是有限制的,每个网页只能同时进行两个长连接,第三个长连接也会被阻塞。
四、实现长连接原理
长连接需要客户端先向服务器端发送一个请求,服务器端进行不间断的检测,做一个死循环,如果有新数据就推送,如果没有新数据,就一直阻塞。服务器端判断里重要一行代码:usleep(10);就是暂停10毫秒,缓解一下CPU压力。大意就是把前端的循环,搬到了服务器端,减少了网络传输的环节。
五、服务器端优化
如果用长连接,必然会给服务器端造成极大的压力,可以考虑放到memcache中;或者为了减小内存的开销,将聊天记录存到文件里。
六、核心代码
chat.php
<html>
<head>
<title>聊天室</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="../jquery.min.js"></script>
<script>
$(function(){
$("#post").click(function(){ var content=$("#content").val();
if(!$.trim(content)){
alert('请填写内容');
return false;
}
$("#content").val(""); $.post("ajax.php", {content:content});});
}) function getData(msg){
if(msg == undefined)
{
msg = '';
}
$.post("get.php",{"msg":msg},function(data){
//var myjson = eval("("+data+")");
if(data){
var chatcontent = '';
var obj = eval('('+data+')');
$.each(obj,function(key,val){
chatcontent += "<div class='username'>"+val['username']+" 说:</div>";
chatcontent += "<div class='content'>"+val['content']+"</div>";
})
$("#chatshow").html(chatcontent);
} getData();
})
} // function getUser(msg){
// if(msg == undefined){
// msg = '';
// }
// $.post("getuser.php",{"msg":msg},function(data){
// //var myjson = eval("("+data+")");
// if(data){
// var chatcontent = '';
// var obj = eval('('+data+')');
// $.each(obj,function(key,val){
// chatcontent += "<div class='username'>"+val['username']+" 说:</div>";
// chatcontent += "<div class='content'>"+val['content']+"</div>";
// })
// $("#chatshow").html(chatcontent);
// }
// getData();
// })
// } getData("one"); // $(function(){
// $("#userlist p").click(function(){
// $("#content").val("@"+$(this).text()+" ");
// })
// }) // $(function(){
// $(document).keypress(function(e){
// if(e.ctrlKey && e.which == 13 || e.which == 10) { // var content=$("#content").val();
// if(!$.trim(content)){
// alert('请填写内容');
// return false;
// }
// $("#content").val("");
// $.post("ajax.php", {content:content});
// }
// })
// //alert(event.clientX+document.body.clientWidth);
// }) /*window.onbeforeunload=function (){
//return("===onbeforeunload===");
if(event.clientX>document.body.clientWidth && event.clientY < 0 || event.altKey){
return("你关闭了浏览器");
}else{
return(document.body.clientWidth);
}
} */ </script>
<style>
#chat{margin:0 auto;}
#chatshow{width:500px;height:400px;overflow:auto;border:1px solid #ccc;float:left;}
#userlist{width:100px;height:400px;overflow:auto;border:1px solid #ccc;float:left;margin-right:2px;}
#userlist p{color:#0F0; cursor:pointer;}
.clearboth{clear:both;}
.username{font-weight:bold;color:#00F;font-size:12px;margin-bottom:3px;margin-top:8px;}
</style>
</head>
<body>
<div id="chat">
<div id="userlist">
<div style="font-size:12px;font-weight:bold;">在线用户列表</div>
<div class="userlist">
<?php
// $dsn = "mysql:host=localhost;dbname=test;charset=utf8'";
// $db = new PDO($dsn, 'root', 'root');
$db = new PDO('mysql:dbname=test;host=127.0.0.1;charset=utf8', 'root', 'adminroot');
$rs = $db->prepare("select * from chat where is_login = '1'");
$rs->execute();
while($row = $rs->fetch()){
echo '<p>'.$row['username'].'</p>';
}
?>
</div>
</div>
<div id="chatshow"></div>
</div>
<div class="clearboth"></div>
<div>
<textarea name="content" id="content" style="width:600px;height:100px"></textarea>
<input type='button' name='tj' id="post" value='发布' >
</div>
</body>
</html>
ajax.php
<?php
/*session_start();
$mem = new Memcache;
$mem->connect("localhost",11211);
if(isset($_POST['content'])){
$con['username'] = $_SESSION["username"];
$con['content'] = $_POST["content"]; $data = $mem->get('chat');
$data[] = $con;
$mem->set("chat",$data,0,0);
}
$mem->close();
*/
if(isset($_POST['content'])){
session_start();
$filename = date("Ymd",time()).".txt";
if(file_exists($filename)){
$content = file_get_contents($filename);
$data = json_decode($content,true);
$con['username'] = $_SESSION["username"];
$con['content'] = $_POST["content"];
$data[] = $con;
$file = fopen($filename,"w");
fwrite($file,json_encode($data));
fclose($file);
}else{
$file = fopen($filename,"w");
$con['username'] = $_SESSION["username"];
$con['content'] = $_POST["content"];
$data[] = $con;
fwrite($file,json_encode($data));
fclose($file);
} } ?>
get.php
<?php
/*require 'conn.inc';
function getData(){
$sql="SELECT count(*) FROM `talkroom`";
$res=mysql_query($sql);
$count = mysql_fetch_row($res); return $count;
}
$old = getData(); while(true){
$new = getData();
if($new[0]>$old[0]){
//echo json_encode($new['data']);
//print_r($new);
echo '2222222222'.'<br/>';
}
//echo '<br />11111111111111111111111111111111111111111111111111111111111111111111';
usleep(1000);
}
*/
/*set_time_limit(0);
$mem = new Memcache;
$mem->connect("localhost",11211); $count = count($mem->get("chat"));
$com = true;
//$mem->delete('chat');
if($_POST['msg'] == "one"){
exit(json_encode($mem->get("chat")));
}
if($_POST['msg'] == "break"){
$com = false;
}
$time1 = time();
while(true){
if($com){
$data = $mem->get("chat");
if(count($data)>$count){
echo json_encode($data);
break;
}
usleep(300);
}else{
break;
}
}
$mem->close();*/ set_time_limit(0);
$filename = date("Ymd",time()).".txt";
if(file_exists($filename)){
$content = file_get_contents($filename);
$data = json_decode($content,true);
$count = count($data);
// echo $count;die;
if($_POST['msg'] == "one"){
exit(json_encode($data));
} while(true){ $contents = file_get_contents($filename);
$datas = json_decode($contents,true);
$counts = count($datas);
if($counts>$count){
echo json_encode($datas);
break;
}
usleep(300);
}
}else{
$file = fopen($filename,"w");
$con['username'] = "系统消息";
$con['content'] = "欢迎来到EPGO聊天室";
$data[] = $con;
fwrite($file,json_encode($data));
fclose($file); exit(json_encode($data)); } ?>
以上就是这次的全部内容!
php实现聊天室功能的更多相关文章
- Netty学习笔记(四) 简单的聊天室功能之服务端开发
前面三个章节,我们使用了Netty实现了DISCARD丢弃服务和回复以及自定义编码解码,这篇博客,我们要用Netty实现简单的聊天室功能. Ps: 突然想起来大学里面有个课程实训,给予UDP还是TCP ...
- 使用epoll实现聊天室功能,同时比较epoll和select的异同
1.首先介绍一下select和epoll的异同,如下(摘抄自https://www.cnblogs.com/Anker/p/3265058.html) select的几大缺点: (1)每次调用sele ...
- [Python] socket发送UDP广播实现聊天室功能
一.说明 本文主要使用socket.socket发送UDP广播来实现聊天室功能. 重点难点:理解UDP通讯流程.多线程.UDP广播收发等. 测试环境:Win10\Python3.5. 程序基本流程:创 ...
- SignalR实现在线聊天室功能
一.在线聊天室 1.新建解决方案 SignalROnlineChatDemo 2.新建MVC项目 SignalROnlineChatDemo.Web (无身份验证) 3.安装SignalR PM> ...
- 03_netty实现聊天室功能
[概述] 聊天室主要由两块组成:聊天服务器端(ChatRoomServer)和聊天客户端(ChatClient). [ 聊天服务器(ChatRoomServer)功能概述 ] 1.监听所有客户端的接入 ...
- PHP 之websocket实现聊天室功能
一.功能界面 具体的详细代码:https://github.com/yangsphp/websocket-master/tree/master 二.具体代码实现 1.前端代码如下 <!DOCTY ...
- 黑科技!仅需 3 行代码,就能将 Gitter 集成到个人网站中,实现一个 IM 即时通讯聊天室功能?
欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 高级架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...
- java web利用mvc结构实现简单聊天室功能
简单聊天室采用各种内部对象不适用数据库实现. 一个聊天室要实现的基本功能是: 1.用户登录进入聊天室, 2.用户发言 3.用户可以看见别人发言 刚才算是简单的需求分析了,现在就应该是进 ...
- 通过WebSocket实现一个简单的聊天室功能
WebSocket WebSocket是一个协议,它是是基于TCP的一种新的网络协议,TCP协议是一种持续性的协议,和HTTP不同的是,它可以在服务器端主动向客户端推送消息.通过这个协议,可以在建立一 ...
- Netty学习笔记(六) 简单的聊天室功能之WebSocket客户端开发实例
在之前的Netty相关学习笔记中,学习了如何去实现聊天室的服务段,这里我们来实现聊天室的客户端,聊天室的客户端使用的是Html5和WebSocket实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...
随机推荐
- AltiumDesigner PCB导入CAD
点击File菜单下的New的PCB,新建PCB文件. 在AD09中点击File菜单下的Import,导入CAD文件 选择要导入的CAD文件,点击打开. 选择单位mm,这里的单位选择要与CAD单位一致, ...
- xmlhttprequest 1.0和2.0的区别,from qq前端哥
阮一峰好文:http://www.ruanyifeng.com/blog/2012/09/xmlhttprequest_level_2.html
- pythone函数基础(7)第三方模块学习
一,time模块学习 import time # print(int(time.time()))#时间戳# res = time.strftime('%Y-%m-%d %H:%M:%S')#取当前格式 ...
- SQL Server XML 查询
[参考1] 18个小实例入门SQLServer XML查询 [参考2] 转载---SQL Server XML基础学习之<5>--XQuery(query)
- ORM初识和数据库操作
ORM简介 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.简单的说,ORM是通过使用描述对象和数据库之 ...
- 3.在自己的bag上运行Cartographer ROS
1.验证自己的bag cartographer ROS提供了一个工具cartographer_rosbag_validate来自动分析包中的数据.在尝试调试cartographer之前运行这个工具. ...
- 编译搭建lnmp+zabbix
搭建nginx 1)基础依赖包安装 yum -y install gcc gcc-c++ vim tree make cmake autoconf yum -y install openssl ope ...
- print('{:15}|{:^9}|{:^9}'.format('', 'lat.', 'long.'))是什么意思?
平台:win10 x64+Python3.7.0 先了解下——Python3 字符串格式化 Python字符串的格式化方法分为两种,分别为占位符(%)和format方式. 占位符方式在Python2. ...
- 字符串相似度算法——Levenshtein Distance算法
Levenshtein Distance 算法,又叫 Edit Distance 算法,是指两个字符串之间,由一个转成另一个所需的最少编辑操作次数.许可的编辑操作包括将一个字符替换成另一个字符,插入一 ...
- 可遇不可求的Question之error: Failed dependencies: MySQLconflicts 错误篇
error: Failed dependencies: MySQLconflicts 错误提示: error: Failed dependencies: ...