服务端 Link to heading

服务端是使用Node.js的ws模块,具体API可以点击这里 –> 点我查看 <–

// 引入express和ws
const express = require('express');
const app = express();
const WebSocket = require('ws');
// 使用express创建一个server
const serve = app.listen(3000,function () {
  console.log('server run 3000');
});
// 把这个server绑定到websocket-server上
// 以后所有的请求都会经过websocket-server
// 如果是websocket连接就会由websocket-server接管,如果是普通连接会由express-server接管
const ws = new WebSocket.Server({
  server: serve
});

// 这里创建的clientsInfo用来保存目前连接的所有用户发送的信息
// clientsUser用来保存连接的用户系统信息,采用自定义数据作为key,用来私发消息
let testData,clientsInfo = [],clientsUser = {};

app.get('/websocket/sendtoken', function(req, res){
  console.log('data',req.query.token);
  testData = req.query.token;
  res.json({
    msg: 'ok',
    token: req.query.token
  })
});

app.get('/websocket/clientsinfo', function(req, res){
  res.json({
    msg: 'ok',
    data: clientsInfo
  })
});

// 获取总连接个数
function allConnections(ws) {
  let i = 0;
  ws.clients.forEach(function each() {
    i+=1
  });
  console.log(`[SERVER] : 共有${i}个连接`);
  return i;
}

// 广播方法
ws.broadcast = function broadcast(data) {
  let num = allConnections(ws);
  ws.clients.forEach(function each(client) {
    client.send('广播'+data +'共有'+ num +'个用户');
  });
  console.log(`[SERVER] 收到客户端消息: ${data},共有${num}个用户`);
}

// 删除用户方法
ws.removeClientInfo = function removeClientInfo(clientsInfo,client) {
  let clientName = client.userName;
  clientsInfo.forEach(function (item,index) {
    if (item.userName === clientName){
      clientsInfo.splice(index,1);
    }
  });
  return clientsInfo;
}

ws.on('connection', function (result) {
  console.log(`[SERVER] 客户端已连接`);
  result.on('message', function (message) {
    let res = JSON.parse(message);
    if (res.used === 'login'){
      // 用户登录后储存用户信息
      clientsUser[res.userName] = result;
      clientsInfo.push(res);
      result.send('from server' + res.userName + '已储存');
      console.log(res.userName + '已储存');
    }
    if(res.used === 'logout'){
      // 用户登出时删除用户信息
      delete clientsUser[res.userName];
      ws.removeClientInfo(clientsInfo,res);
      result.send('from server' + res.userName + '已删除');
      console.log(res.userName + '已删除');
    }
    // 管理端查看 发送当前连接数
    if(res.used === 'manage'){
      let currentClients = JSON.stringify(clientsInfo);
      result.send(currentClients);
      console.log(res.userName + '信息已发送');
    }
    // 管理端给指定用户发送websocket信息
    if (res.used === 'send'){
      let sendUser = clientsUser[res.userName];
      sendUser.send('hello,world!')
    }
    // 管理端 群发除了自己
    if (res.used === 'sendall'){
      console.log('接收到群发消息');
      ws.clients.forEach(function each(client) {
        if (client !== result) {
          client.send('广播消息');
        }
      });
    }
    // 广播消息
    // ws.broadcast(res.msg);
    // console.log(`[SERVER] 收到客户端消息: ${res.msg}`);
    // 单发消息
    // result.send(`ECHO: ${res.msg}`, (err) => {
    //   if (err) {
    //     console.log(`[SERVER] error: ${err}`);
    //   }else {
    //     console.log(`[SERVER] 收到客户端消息: ${res.msg}`);
    //   }
    // });

  })
  result.on('close', function (closeResult) {
    console.log(`[SERVER] 客户端${closeResult}连接已关闭`);
  });
});

客户端 Link to heading

客户端其实都一样,应为html5已经全面支持WebSocket技术,可以直接new出来了!!!

$(function () {
  // 建立websocket连接
    let ws = new WebSocket("ws://192.168.0.110:3000");
    ws.getClientsInfo = function getClientsInfo() {
      let WsData = JSON.stringify({
        userName: 'manage',
        token: 'manage_123456789',
        used: 'manage'
      });
      // 发送消息
      ws.send(WsData);
      console.log('数据已经发送');
      // 监听消息
      ws.onmessage = function (evt){
        let msg = JSON.parse(evt.data);
        console.log(msg);
        dataToHtml(msg);
        $('.send').on('click',function (e) {
          let rst = {
            userName: e.target.dataset.username,
            used: 'send'
          };
          console.log(rst);
          ws.send(JSON.stringify(rst));
          ws.onmessage = function (evt){
            let msg = evt.data;
            console.log(msg);
          };
        })
      };
    };
    // 监听连接事件
    ws.onopen = function () {
      console.log('Web Socket 已连接');
      ws.getClientsInfo();
    }
    
    // 群发
    $('#sendAll').on('click',function () {
      let msg = {
        used: 'sendall'
      }
      ws.send(JSON.stringify(msg));
      ws.onmessage = function (evt){
        let msg = evt.data;
        console.log(msg);
        alert('群发成功')
      };
    })
    
    function dataToHtml(data) {
      let str = '';
      data.forEach(function (item,index) {
        str += `<div class="item flex-12 flex center-center">
                  <div class="flex-1 text-center">${index+1}</div>
                  <div class="flex-4 text-center">${item.userName}</div>
                  <div class="flex-4 text-center">${item.token}</div>
                  <div class="flex-1 text-center">${item.used}</div>
                  <div class="flex-2 text-center">
                    <button class="send" data-username="${item.userName}">发送</button>
                  </div>
                </div>`
      })
      document.getElementById('itemGrounp').innerHTML = str;
    }
  })