WebSocket

WebSockets 是一种先进的技术。它可以在用户的浏览器和服务器之间打开交互式通信会话。使用此API,您可以向服务器发送消息并接收事件驱动的响应,而无需通过轮询服务器的方式以获得响应。

Node.js端

Node.js这边使用的是ws库,可以直接npm install ws安装。然后我们创建一个app.js,初始化一些代码

//server.js
var websocketServer = require('ws').Server,
    wss = new websocketServer({ port: 8033 })
var clients = [] //作为一个连接池,存储连接的用户信息
var cacheContent = [] //存储历史消息
var id = 0 //给每一个用户一个id

常用API

  • connection 连接方法,有新的客户端接入就会触发这个方法,一般使用
    wss.on('connection',function(ws){
      //做一些初始化操作
    })    
  • message 监听客户端发来的消息
    wss.on('message',function(message){
      //拿到消息message后进行一些操作
    })
  • close 监听客户端断开
    wss.on('close',function(ws){
      //客户端断开之后执行一些操作
    })
  • send 向客户端发送消息
    wss.send(msg) 这里要注意的是若发送的数据不是基本数据类型,则需要用JSON.stringify(obj)转化一下,即是
    let obj = {name:'David',age:18}
    wss.send(JSON.stringify(obj))

浏览器端

实例化一个WebSocket

var ws = new WebSocket(url) url是服务端开启的socket服务地址

常用API

  • onopen 初始化事件,刚连上的时候就会触发这个事件
    ws.onopen = function(e){
      console.log('连接到socket服务')
    }
  • onmessage 接收服务端发送来的信息
    ws.onmessage = function(event){
      console.log(event.data)
    }
  • close 断开连接事件
    ws.onclose = function(e){
      console.log(e)
      console.log('连接断开')
    }

简易聊天室栗子

话不多说,直接上代码吧,代码也非常简单,当做自己使用的一次记录,不得不说socket真是个好东西,双工通信的时候比轮询好多了,知道了基本的用法,想怎么拓展都可以了。

//index.html
<body>
    <h2 id="id"></h2> //显示访问者的id
    <input type="text" id="text" />
    <input type="button" onclick="sendMessage()" value="发送" />
    <div id="content"></div>
    <script>
      var ws = new WebSocket("ws://localhost:8033");

      ws.onopen = function(e) {
        console.log("连接到socket服务");
      };
      //这个接收消息方法要和服务端连起来一起看
      ws.onmessage = function(event) {
        let data = JSON.parse(event.data);
        let type = data.type;
        let id = data.id;
        console.log(event);
        switch (type) {
          case "getId":
            document.getElementById("id").innerHTML = `欢迎您,游客${id}`;
            break;
          case "getContent":
            let content = data.content;
            document.getElementById(
              "content"
            ).innerHTML += `<div>游客${id}说:${content}<div>`;
            break;
          default:
            break;
        }
      };
      ws.onclose = function(e) {
        console.log("连接断开");
      };
      //发送消息方法
      function sendMessage() {
        ws.send(document.getElementById("text").value);
        document.getElementById("text").value = "";
      }
    </script>
  </body>

服务端的代码如下

var websocketServer = require('ws').Server,
    wss = new websocketServer({ port: 8033 })
//连接池
var clients = []
var cacheContent = []
var id = 0
wss.on('connection', function (ws) {
    //将该连接加入连接池
    let uid = id++ 
    clients.push(ws)
    //给新用户一个id
    ws.send(JSON.stringify({ 'msg': '欢迎你', 'id': uid, 'type': 'getId' }))
    //给新来的用户发送旧消息
    getCacheContent(ws)
    ws.on('message', function (message) {
        clients.forEach(ws1 => {
            let obj = {}
            obj.content = message
            obj.id = uid
            obj.type = 'getContent'
            cacheContent.push(obj)
            ws1.send(JSON.stringify(obj))
        })
    })
    //断开连接时将其移出
    ws.on('close', function (ws) {
        let clientIndex = clients.indexOf(ws)
        clients.splice(clientIndex, 1)
    })
})
function getCacheContent(ws){
    cacheContent.forEach(item=>{
        ws.send(JSON.stringify(item))
    })
}