通过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