1.websocket上车指南
首先需要搞清楚的是websocket到底是什么,它有什么作用。
websocket是一种服务器主动给客户端发送消息的技术。
WebSocket是一种通信协议,可在单个TCP连接上进行全双工通信。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以建立持久性的连接,并进行双向数据传输。
websocket是一种通信协议。区别与HTTP协议,HTTP协议只能实现客户端请求,服务端响应的这种淡向通信。而WebSocket可以实现客户端与服务端的双向通讯,说白了,最大也是最明显的区别就是可以做到服务端主动将消息推送给客户端。
除此之外还有以下特点:
- 握手阶段采用 HTTP 协议
- 数据格式轻量,性能开销小。客户端与服务端进行数据交换时,服务端到客户端的数据包头只有2到10字节,客户端到服务端需要加上另外4字节的掩码。HTTP每次都需要携带完整头部。
- 更好的二进制支持,可以发送文本,和二进制数据
- 没有同源限制,客户端可以与任意服务器通信
- 协议标识符是ws(如果加密,则是wss),请求的地址就是后端支持websocket的API。
在html5之前,因为http协议是无状态的,要实现浏览器与服务器的实时通讯,如果不使用 flash、applet 等浏 览器插件的话,就需要定期轮询服务器来获取信息。这造成了一定的延迟和大量的网络通讯。随着HTML5 的出现, 这一情况有望彻底改观,它就是 webSocket 。
2.socket.io
Socket.IO是一个完全由JavaScript实现、基于Node.js、支持webSocket的协议用于实时通信、跨平台的开源框 架,它包括了客户端的JavaScript和服务器端的Node.js。
Socket.IO 实现了基于事件的实时双向通信。可以工作在任意平台、浏览器或设备,专注于可靠性和速度,这也 是它的特点。
socket.io实际上是webSocket的封装库,它们的关系类似jQuery与Javascript的关系,或者是express与Node.js 的关系
引入:
这里建议使用cnpm引入,因为我在使用npm引入时总是无故error
cnpm i socket.io express
首先应确保有node环境,因为前面说到socket.io是基于nodejs的。
实例(实现服务器主动向客户端发送消息):
服务器端app.js:
const express = require('express')();
const http = require('http').Server(express);
const io = require('socket.io')(http);
express.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
})
io.on('connection', function (socket) {
socket.emit('meg','你好');
socket.on('data',function (data) {
console.log(data);
})
})
http.listen(8080, function () {
console.log('您已打开服务');
})
客户端index.js
<h1></h1>
<script src="https://cdn.bootcdn.net/ajax/libs/socket.io/3.1.3/socket.io.js"></script>
<script>
var socket = io();
var h1 = document.getElementsByTagName('h1')[0];
socket.on('connect', function () {
console.log('与服务器端连接成功!')
})
socket.on('meg', function (msg) {
console.log(msg);
h1.innerHTML = msg;
})
socket.emit('data', 'hello server');
</script>
3.HTML5 webSocket
webSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
在webSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速 通道。两者之间就直接可以数据互相传送。
浏览器通过 JavaScript 向服务器发出建立 webSocket 连接的请求,连接建立以后,客户端和服务器端就可以通 过 TCP 连接直接交换数据。
当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收 服务器返回的数据。
引入:
cnpm i nodejs-websocket -S-dev
webSocket相较于HTTP来说,有很多的优点,主要表现在webSocket只建立一个TCP连接,可以主动推送数据 到客户端,而且还有更轻量级的协议头,减少数据传送量。所以webSocket暂时来说是实时通讯的最佳协议了。
案例:(做一个实时交互的案例,index.js为服务器,game1与服务器进行连接并且处理发送请求,服务器再将数据发送给game2)
index.js
var ws = require("nodejs-webSocket");
console.log("开始建立连接...")
var game1 = null,
game2 = null,
game1Ready = false,
game2Ready = false;
var server = ws.createServer(function (conn) {
conn.on("text", function (str) {
console.log("收到的信息为:" + str)
if (str === "game1") {
game1 = conn;
game1Ready = true;
conn.sendText("success");
}
if (str === "game2") {
game2 = conn;
game2Ready = true;
}
if (game1Ready && game2Ready) {
game2.sendText(str);
}
conn.sendText(str)
})
conn.on("close", function (code, reason) {
console.log("关闭连接")
});
conn.on("error", function (code, reason) {
console.log("异常关闭")
});
}).listen(8001)
console.log("webSocket建立完毕")
以上代码的大意就是服务器端使用webSocket开启服务,并且开始监听客户端的请求,如果过来的时game1,那么发送对应消息,如果时game2,则处理对应请求game1Ready时game的状态,用来判断是否同时在线,若同时在线,则将str发送给game2.
game1.html
<!doctype html>
<htmlang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.box {
text-align: center;
margin-top: 200px;
}
#mess {
text-align: center
}
.value {
width: 200px;
height: 200px;
border: 1px solid;
text-align: center;
line-height: 200px;
display: inline-block;
}
</style>
</head>
<body>
<div id="mess">正在连接...</div>
<div class="box">
<div class="value" id="value1">小明</div>
<div class="value" id="value2">小王</div>
<div class="value" id="value3">小张</div>
</div>
<script>
var mess = document.getElementById("mess");
if (window.WebSocket) {
var ws = new WebSocket('ws://127.0.0.1:8001');
ws.onopen = function (e) {
console.log("连接服务器成功");
ws.send("game1");
}
ws.onclose = function (e) {
console.log("服务器关闭");
}
ws.onerror = function () {
console.log("连接出错");
}
ws.onmessage = function (e) {
mess.innerHTML = "连接成功"
console.log(e.data);
document.querySelector(".box").onclick = function (e) {
var time = new Date();
ws.send(time + " game1点击了“" + e.target.innerHTML + "”");
}
}
}
</script>
</body>
<html>
首先于服务其建立连接,成功时发送对应消息。然后处理逻辑给服务器发送对应消息。
game2.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.box {
text-align: center;
margin-top: 200px;
}
#mess {
text-align: center
}
</style>
</head>
<body>
<div id="mess"></div>
<script>
var mess = document.getElementById("mess");
if (window.WebSocket) {
var ws = new WebSocket('ws://127.0.0.1:8001');
ws.onopen = function (e) {
console.log("连接服务器成功");
ws.send("game2");
}
ws.onclose = function (e) {
console.log("服务器关闭");
}
ws.onerror = function () {
console.log("连接出错");
}
ws.onmessage = function (e) {
var time = new Date();
mess.innerHTML += time + "的消息:" + e.data + "<br>"
}
}
</script>
</body>
</html>
首先于服务其建立连接,成功时发送对应消息。然后处理逻辑(接受服务器发来的消息)