WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。
DEMO如下
// client side file
let socket = new WebSocket('ws://localhost:9999');
// 当连接成功执行回调函数
socket.onopen = function () {
console.log('客户端连接成功');
// 向服务器发送一个消息
socket.send('这是客户端发给服务器的消息');
}
// 绑定事件是用加属性的方式
socket.onmessage = function (res) {
console.log('收到服务器端的响应是', res);
}
// server side file
/* npm i ws -S */
/* 用ws模块启动一个websocket服务器,监听 9999 端口 */
let WebSocketServer = require('ws').Server;
let wsServer = new WebSocketServer({port: 9999});
wsServer.on('connection', socket=>{
console.log('服务器连接成功');
socket.on('message', msg=>{
console.log('从客户端接收到的信息为'+msg);
socket.send('这是从服务器发送到客服端的信息');
})
})
简单模拟智能客服聊天
<template>
<div class="wrap">
<ul>
<li v-for="(item, index) in dialogs" :key="index">
<p :class="item.self ? 'fr': 'fl'">{{item.sendContent || item.acceptContent}}</p>
</li>
</ul>
<div class="send-cont">
<input v-model="sendCont">
<input type="button" @click="send" value="发送">
</div>
</div>
</template>
<script>
let socket = new WebSocket("ws://localhost:9999");
export default {
data() {
return {
dialogs: [],
sendCont: "",
isConnect: false
};
},
mounted() {
socket.onopen = () => {
this.isConnect = true;
};
},
methods: {
send() {
if (this.isConnect) {
console.log("客户端连接成功");
// 向服务器发送一个消息
socket.send(this.sendCont);
this.dialogs.push({ sendContent: this.sendCont, self: true });
// 绑定事件是用加属性的方式
socket.onmessage = res => {
setTimeout(() => {
this.dialogs.push({ acceptContent: res.data });
}, Math.random() * 2000);
};
}
}
}
};
</script>
<style scoped>
* {
padding: 0;
margin: 0;
}
.fl {
float: left;
}
.fr {
float: right;
}
li::before {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.wrap {
position: relative;
width: 380px;
margin: auto;
height: 600px;
background-color: #eee;
padding: 10px;
}
.wrap ul {
overflow: auto;
height: 550px;
}
li {
list-style: none;
margin: 2px;
}
li:nth-child(even) p {
background-color: rgb(86, 107, 177);
}
li p {
font-size: 20px;
font-family: "Microsoft Yahei", serif, Arial, Helvetica, sans-serif;
border-radius: 6px;
padding: 4px;
margin: 2px 4px;
white-space: wrap;
text-align: left;
}
li p.fr {
background-color: rgb(61, 185, 30);
}
.send-cont {
position: absolute;
bottom: 10px;
z-index: 999;
width: 98%;
margin: auto;
}
.send-cont input {
display: inline-block;
outline: none;
border: 2px solid #080;
border-radius: 6px;
line-height: 30px;
font-size: 16px;
text-align: left;
}
.send-cont input:first-child {
width: 70%;
}
.send-cont input[type="button"] {
width: 20%;
background-color: #080;
color: #fff;
text-align: center;
padding: 1px;
}
</style>
const contents = ['你好', 'hi', 'hello', 'nice to meet you', 'how are you', 'how do you do']
let WebSocketServer = require('ws').Server;
let wsServer = new WebSocketServer({port: 9999});
wsServer.on('connection', socket=>{
console.log('服务器连接成功');
socket.on('message', msg=>{
console.log('从客户端接收到的信息为'+msg);
socket.send(contents[parseInt(Math.random()*contents.length)]);
})
})