1. webSocket解读
2. 使用webSocket
- 客户端
- 服务端
- 界面展示
参考文章:
https://www.cnblogs.com/myzhibie/p/4470065.html
https://www.liaoxuefeng.com/wiki/1022910821149312/1103303693824096
1. webSocket解读
WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道(全双工通信),比如说,服务器可以在任意时刻发送消息给浏览器,浏览器也可以在任意时刻发消息给服务器。
为什么传统的HTTP协议不能做到WebSocket实现的功能?这是因为HTTP协议是一个请求-响应协议,请求必须先由浏览器发给服务器,服务器才能响应这个请求,再把数据发送给浏览器。换句话说,浏览器不主动请求,服务器是没法主动发数据给浏览器的。
具体来讲,我们在客户端构建一个websocket实例,并且为它绑定一个需要连接到的服务器地址,当客户端连接服务端的时候,会向服务端发送一个类似下面的http报文
GET ws://localhost:3000/ws/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Origin: http://localhost:3000
Sec-WebSocket-Key: client-random-string
Sec-WebSocket-Version: 13
可以看到,这是一个http get请求报文,注意该报文中有一个upgrade首部,它的作用是告诉服务端需要将通信协议切换到websocket,如果服务端支持websocket协议,那么它就会将自己的通信协议切换到websocket,同时发给客户端类似于以下的一个响应报文头
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string
返回的状态码为101,表示同意客户端协议转换请求,并将它转换为websocket协议。
以上过程都是利用http通信完成的,称之为websocket协议握手(websocket Protocol handshake),通过握手,客户端和服务端就建立了websocket连接,以后的通信走的都是websocket协议了。所以总结为websocket握手需要借助于http协议,建立连接后通信过程使用websocket协议。同时需要了解的是,该websocket连接还是基于我们刚才发起http连接的那个TCP连接。一旦建立连接之后,我们就可以进行数据传输了,websocket提供两种数据传输:文本数据和二进制数据。
websocket能够提供低延迟,高性能的客户端与服务端的双向数据通信。
它颠覆了之前web开发的请求处理响应模式,并且提供了一种真正意义上的客户端请求,服务器推送数据的模式。
2. 使用webSocket
- 客户端
demo页面
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
body{
padding: 20px;
}
.msg_box{
color: #333;
border: 1px solid #ddd;
height: 200px;
overflow-y: auto;
}
.msg_box li{
padding: 4px 2px;
}
.message{
width: 90%;
/* margin: 0 10px; */
display: inline-block;
/* text-align: center; */
height: 40px;
line-height: 40px;
font-size: 16px;
border: none;
padding-left: 10px;
}
.form{
width:100%;
border: 1px solid #eee;
border-top: 0;
}
.connect{
padding: 8px 30px;
margin-bottom: 10px;
font-size: 16px;
border-radius: 2px;
border: none;
background: #00A3FF;
color: #fff;
}
#send{
float: right;
border: 0;
border-left: 1px solid #eee;
width: 9%;
height: 40px;
background: #fff;
color: #aaa;
}
</style>
</head>
<body>
<input type="button" value="建立连接" id="connect" class="connect"/>
<div class="msg_box">
<ul id="content"></ul>
</div>
<form class="form">
<input type="text" placeholder="请输入发送的消息" class="message" id="message"/>
<input type="button" value="发送" id="send"/>
</form>
<script>
var oUl=document.getElementById('content');
var oConnect=document.getElementById('connect');
var oSend=document.getElementById('send');
var oInput=document.getElementById('message');
var ws=null;
oConnect.onclick=function(){
ws=new WebSocket('ws://localhost:5000');
ws.onopen=function(){
oUl.innerHTML+="<li>客户端已连接</li>";
}
ws.onmessage=function(evt){
console.log(evt)
oUl.innerHTML+="<li>"+evt.data+"</li>";
}
ws.onclose=function(){
oUl.innerHTML+="<li>客户端已断开连接</li>";
};
ws.onerror=function(evt){
oUl.innerHTML+="<li>"+evt.data+"</li>";
};
};
oSend.onclick=function(){
if(ws){
ws.send(oInput.value);
}
}
</script>
</body>
</html>
这里利用new WebSocket创建一个指定连接服务端地址的ws实例,然后为该实例注册onopen(连接服务端),onmessage(接受服务端数据),onclose(关闭连接)以及ws.send(建立连接后)发送请求。上面说了那么多,事实上可以看到html5 websocket API本身是很简单的一个对象和它的几个方法而已。
- 服务端
服务端是用nodejs搭建的(确定电脑中已经有nodejs, npm)
cd到项目根目录下,安装nodejs-websocket包
npm install nodejs-websocket
安装好以后,在根目录下创建一个js: server.js,内容如下
var ws = require('nodejs-websocket');
var port=5000
var server = ws.createServer(function(conn){
// 受到连接触发
console.log('new connection');
// 收到信息触发
conn.on("text",function(str){
console.log("received"+str)
boardcast(str) // 广播消息
conn.sendText(str) // 发送 数据
})
// 断开连接触发
conn.on("close",function(code,reason){
console.log("connection closed")
})
// 出错触发
conn.on("error",function(err){
console.log("header err")
console.log(err)
})
// 广播
function boardcast(str){
// server.connections 保存每个连接进来的用户 //
server.connections.forEach(function(conn){ // .forEach 是调用数组里每个元素 //
conn.sendText(str)
})
}
}).listen(port)
console.log("websocket server listen port is" + port)
- 界面展示
在浏览器中打开两个页面,用于模拟两个客户端
点击:建立连接,开启webSocket通信
这时候就可以尝试在两端收发消息啦~