持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
我们知道http是请求应答的模式,基于半双工通信,但是很多时候我们需要有全双工通信,如消息推送这种功能,在没有全双工通信的时候,我们只能用轮询的方式来进行,但是这种方式要服务器不断的请求,资源消耗较大,于是h5提出了新的规范,就是今天要说的websocket
特点
- websocket是建立在TCP协议之上的。
- 支持的擦混输类型多,可以是文本也可以是二进制文件。
- 没有同源限制,不会发生跨域的警告。
- 协议标志是ws,如果是加密的那么就是wss(这和http和https很像)。
连接过程
我们知道http是通过三次握手建立连接的,断开的时候再进行四次挥手,其过程是一个请求应答的过程,响应的前提是要接收到请求,而websocket是在客户端发起http请求后,经过三次握手建立起TCP连接,htto请求中存放这websocket支持的版本号等具体信息,建立连接后就可以正常通信了,这种通信是全双工通信。
websocket相比较http的缺点和优点
- 优点
建立连接后,进行通信的请求头是很小的,减少了资源的消耗。
服务器可以向客户端主动推送消息了。
- 缺点
部分浏览器尚未支持且已经支持的浏览器现在支持的程度和方式也不太一样。
体验websocket
我们通过nodejs-websocket这个包来创建我们的websocket服务,其对websocket进行了一些封装便于我们使用:
-
ws.createServer([options], [callback]):创建一个 server 对象
-
ws.connect(URL, [options], [callback]):创建一个 connect 对象,一般由客户端链接服务端 websocket 服务时创建
服务端代码
var ws = require("nodejs-websocket")
var port = 8010;
var user = 0;
// 创建一个连接
var server = ws.createServer(function (conn) {
console.log("创建一个新的连接--------");
user++;
conn.nickname="user" + user;
conn.fd="user" + user;
var mes = {};
mes.type = "enter";
mes.data = conn.nickname + " 进来啦"
broadcast(JSON.stringify(mes)); // 广播
//向客户端推送消息
conn.on("text", function (str) {
console.log("回复 "+str)
mes.type = "message";
mes.data = conn.nickname + " 说: " + str;
broadcast(JSON.stringify(mes));
});
//监听关闭连接操作
conn.on("close", function (code, reason) {
console.log("关闭连接");
mes.type = "leave";
mes.data = conn.nickname+" 离开了"
broadcast(JSON.stringify(mes));
});
//错误处理
conn.on("error", function (err) {
console.log("监听到错误");
console.log(err);
});
}).listen(port);
function broadcast(str){
server.connections.forEach(function(connection){
connection.sendText(str);
})
}
客户端代码
<html>
<body>
<h1>Websocket简易聊天</h1>
<div id="app">
<input id="sendMsg" type="text" />
<button id="submitBtn">发送</button>
</div>
</body>
<script type="text/javascript">
//在页面显示聊天内容
function showMessage(str, type) {
var div = document.createElement("div");
div.innerHTML = str;
if (type == "enter") {
div.style.color = "blue";
} else if (type == "leave") {
div.style.color = "red";
}
document.body.appendChild(div);
}
//新建一个websocket
var websocket = new WebSocket("ws://192.168.137.128:8010");
//打开websocket连接
websocket.onopen = function () {
console.log("已经连上服务器----");
document.getElementById("submitBtn").onclick = function () {
var txt = document.getElementById("sendMsg").value;
if (txt) {
//向服务器发送数据
websocket.send(txt);
}
};
};
//关闭连接
websocket.onclose = function () {
console.log("websocket close");
};
//接收服务器返回的数据
websocket.onmessage = function (e) {
var mes = JSON.parse(e.data); // json格式
showMessage(mes.data, mes.type);
};
</script>
</html>