Node.js服务端08-WebSocket

152 阅读1分钟

应用场景

弹幕

媒体聊天

协同编辑

基于位置的应用

体育实况更新

股票基金报价实时更新

WebSocket并不是全新的协议,而是利用了HTTP协议进行连接,首先,WebSocket连接必须由浏览器发起,因为请求协议是一个标准HTTP请求,格式如下:

GET ws://localhost:3000/ws/chat HTTP/1.1
Host:localhost
Connection:Upgrade
Origin:http://localhost:3000
Set-WebSocket-Key:client-random-string
Set-WebSocket-Version:13

1、安装ws

2、创建socket服务,配置端口号

const WebSocketServer = WebSocket.WebSocketServer
const wss = new WebSocketServer({ port: 8080 })

3、服务端发送消息, 第一个参数ws,websocket连接,第二个参数req

//服务端发送消息, 第一个参数ws,websocket连接,第二个参数req
wss.on('connection', function connection(ws, req) {
 
})

4、服务端接收消息

//服务端发送消息, 第一个参数ws,websocket连接,第二个参数req
wss.on('connection', function connection(ws, req) {
  
  //服务端接收消息
  ws.on('message', function message(data) {
    
  })

 
})

5、创建发送消息类型,验证token,发送各种类型消息

//服务端发送消息, 第一个参数ws,websocket连接,第二个参数req
wss.on('connection', function connection(ws, req) {
  const myURL = new URL(req.url, 'http://127.0.0.1:3000')
  const token = myURL.searchParams.get('token')
  console.log(token);
  //验证token
  const payload = JWT.verify(token)

  if (payload) {
    ws.send(createMessge(WebSocketType.GroupChat, null, '欢迎欢迎,热烈欢迎,进入聊天室'))
    ws.user = payload

    //群发
    sendAll()
  } else {
    ws.send(createMessge(WebSocketType.Error, null, 'token过期'))
  }

  //服务端接收消息
  ws.on('message', function message(data) {
    // console.log('received:%s', data);
    // //转发给其他人

    const msgObj = JSON.parse(data)

    switch (msgObj.type) {
      case WebSocketType.GroupList:

        ws.send(createMessge(WebSocketType.GroupList, null,
          JSON.stringify(Array.from(wss.clients).map(item => item.user))))
        break;
      case WebSocketType.GroupChat:
        console.log(msgObj.data);
        wss.clients.forEach(function each(client) {
          if (client.readyState === WebSocket.OPEN) {
            client.send(createMessge(WebSocketType.GroupChat, ws.user, msgObj.data), {binary: false})
          }
        })
        break;
      case WebSocketType.SingleChat:
        wss.clients.forEach(function each(client) {
          if (client.user.username === msgObj.to && client.readyState === WebSocket.OPEN) {
            client.send(createMessge(WebSocketType.SingleChat, ws.user, msgObj.data), {binary: false})
          }
        })
        break;
      default:
        break;
    }
  })

  ws.on('close', ()=>{
    wss.clients.delete(ws.user)
    // console.log(ws.user);
    sendAll()
  })
})

const WebSocketType = {
  Error: 0, //错误
  GroupList: 1,
  GroupChat: 2,
  SingleChat: 3
}

function createMessge(type, user, data) {
  return JSON.stringify({
    type,
    user,
    data
  })
}

function sendAll() {
  wss.clients.forEach(function each(client) {
    if (client.readyState === WebSocket.OPEN) {
      client.send(createMessge(WebSocketType.GroupList, null,
        JSON.stringify(Array.from(wss.clients).map(item => item.user))))
    }
  });
  
}