通过http长连接和http短连接及websocket实现在线即时通讯聊天

聊天室使我们日常生活中经常用到的,比如微信群聊,今天我带大家了解一下通过三种技术手段可以实现聊天室的功能,主要分为HTTP长连接、HTTP短连接、websocket。UDP通讯、TCP通讯,今天我们主要来讲怎么用http长短连接及websocket来实现即时通讯。
一、什么是HTTP长连接、HTTP短连接、websocket
在HTTP/1.0中默认使用http短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。
而从HTTP/1.1起,默认使用长连接,用以保持连接特性,提高传输的效率和减低服务器的开销。使用长连接的HTTP协议,会在响应头加入这行代码:
Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
websocket是html5的新特性,WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
二、http长连接实现即时聊天
主要通过ajax长连接后端php,后端php一直定时监控消息,有新消息就即时反馈给浏览器,重新开始新的长连接,及时性相对比较高。<?php
function writefile($file_name, $text) {
$handle = fopen($file_name, "a");
if (flock($handle, LOCK_EX)) {
fwrite($handle, $text.'\n');
flock($handle, LOCK_UN);
}
fclose($handle);
}
$_talklistfile = "../Data/talklist.txt";
if (!file_exists($_talklistfile)) {
file_put_contents($_talklistfile, "");
}
if (!empty($_POST['action'])) {
switch ($_POST['action']) {
case "getwords":
$_mtime = $_POST['mtime'];
$i = 0;
while (true) {
usleep(500000); //0.5秒
$i++;
if ($i >= 40) {
echo json_encode(array('error' => true));
exit();
}
//清空文件缓存
clearstatcache();
//如果文件修改时间大于用户那边的时间,就说明有更新
$_newmtime = filemtime($_talklistfile);
if ($_newmtime > $_mtime || $_mtime == 0) {
echo json_encode(array('error' => false, "data" => file_get_contents($_talklistfile), "mtime" => $_newmtime));
exit();
}
}
break;
case "sayword":
$_words = $_POST['words'];
$_uid = $_POST['uid'];
writefile($_talklistfile, '用户'.$_uid." ".date('H:i:s', time())."说".$_words); //写入聊天文件
echo json_encode(array('error' => false));
exit();
break;
default:
break;
}
} else {
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ajax长轮询实现聊天</title>
<script id="bfwone" data="dep=jquery.17&err=0" type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/bfwone.js"></script>
<script type="text/javascript">
var mtime = 0;
//生成唯一字符串
function randomString(len) {
len = len || 32;
var $chars = '2345678';
var maxPos = $chars.length;
var pwd = '';
for (i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
//发送消息
function saywords() {
var words = $("#words").val();
if (words == "") {
alert('说点啥');
return;
}
$.ajax({
type: "POST",
dataType: "json",
url: "/ajaxtalk2.php",
data: {
action: "sayword",
words: words,
uid: $("#username").val()
}, //40秒后无论结果服务器都返回数据
success: function(ret, textStatus) {
if (ret.error == false) {
$("#words").val("");
}
},
});
}
//长连接监听有没有新消息
function listenwords() {
$.ajax({
type: "POST",
dataType: "json",
url: "/ajaxtalk2.php",
timeout: 30000,
//ajax请求超时时间30秒
data: {
action: "getwords",
mtime: mtime,
},
//40秒后无论结果服务器都返回数据
success: function(ret, textStatus) {
if (ret.error == false) {
mtime = ret.mtime;
$("#msg").html(ret.data.replace(/\\n/g, "</br>"));
}
listenwords(); //循环监听
},
//Ajax请求超时,继续查询
error: function(XMLHttpRequest, textStatus, errorThrown) {
if (textStatus == "timeout") {
$("#msg").append("<br>[超时]");
listenwords();
}
}
});
}
bready(function() {
$("#username").val(randomString(6));
listenwords();
$("#btn").bind("click", function() {
saywords();
});
});
</script>
<...点击查看剩余70%
网友评论0