18

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)]);
    })
})

落霞与孤鹜齐飞
188 声望4 粉丝