1.目前的聊天技术有下面几种:
- 长连接:指在一个连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,就保持连接长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是短连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,下次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。
- 长轮询:轮询的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。
- WebSocket:WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输
2.WebSocket
-
来源
长连接和长轮询都比较消耗服务器资源,在这种情况下HTML5定义了webSocket协议,能更好的节省服务器资源和宽带,并且能够更实时地进行通讯。 -
优点
- 较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。
- 更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。
- 保持连接状态。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
- 更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
- 可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
- 更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。
-
握手协议
WebSocket 是独立的、创建在 TCP 上的协议。
Websocket 通过HTTP/1.1 协议的101状态码进行握手。
为了创建Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”(handshaking)。
3.webSocket在nodejs中的基本使用
案例目录:
image.png
1.点对点.js
var http = require("http");
var fs = require("fs");
var server = http.createServer(function(req,res){
fs.readFile("./index.html",function(err,data){
res.writeHeader(200,{"Content-Type":"text/html ;charset=utf-8"});
res.end(data);
});
})
//创建io对象
var io = require("socket.io")(server);
//监听连接事件
io.on("connection",function(socket){
console.log("一个客户连接了");
socket.on('qingqiu',function(msg){
//点的点
socket.emit('fanhui',"返回"+msg);
})
})
server.listen(3000,"127.0.0.1");
2.瀑布模式.js
//引包
var http = require('http');
var fs = require('fs');
//创建服务
var server = http.createServer(function(req,res){
res.writeHeader(200,{'Content-Type':'text/html ;charset=utf-8'});
fs.readFile("index.html",function(err,data){
res.end(data);
})
})
//创建通讯io
var io = require('socket.io')(server);
//出发连接事件
io.on('connection',function(socket){
socket.on('qingqiu',function(msg){
//瀑布模式
io.emit("fanhui",msg);
})
})
server.listen(3000,'127.0.0.1');
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>socket</title>
</head>
<body>
<input type="text" placeholder="要发送的消息内容"/>
<botton>发送</botton>
</body>
</html>
//关键步骤引入socket.io.js
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io();
document.querySelector("botton").onclick = function(e){
e.preventDefault();
console.log("---");
socket.emit("qingqiu",document.querySelector("input").value);
}
socket.on("fanhui",function(msg){
var p = document.createElement("p");
p.innerHTML = msg;
document.body.appendChild(p);
console.log(msg);
})
</script>
网友评论