chencl1986/Blog

Nodejs教程19:WebSocket之一:使用Socket.io建立WebSocket应用

chencl1986 opened this issue · 0 comments

阅读更多系列文章请访问我的GitHub博客,示例代码请访问这里

WebSocket的优势

  1. 性能高。

    根据测试环境数据的不同,大约会比普通Ajax请求高2-10倍。
    HTTP是文本协议,数据量比较大。

    而WebSocket是基于二进制的协议,在建立连接时用的虽然是文本数据,但之后传输的都是二进制数据,因此性能比Ajax请求高。

  2. 双向通信。

    如果是普通Ajax请求,需要实时获取数据,只能用计时器定时发送请求,这样会浪费服务器资源和流量。

    而通过WebSocket,服务器可以主动向前端发送信息。

  3. 安全性高

    由于WebSocket出现较晚,相比HTTP协议,在安全性上考虑的更加充分。

接下来,尝试用Socket.io建立一个基于WebSocket的双向通信。

Socket.io

Socket.io是在使用WebSocket时的一个常用库,它会自动判断在支持WebSocket的浏览器中使用WebSocket,在其他浏览器中,会使用如flash等方式完成通信。

  1. 操作简单
  2. 兼容低端浏览器,如IE6
  3. 自动进行数据解析
  4. 自动重连 若出现连接断开的情况,WebSocket会进行自动重连。

使用Socket.io建立一个WebSocket应用

服务端示例代码:/lesson19/server.js

const http = require('http')
const io = require('socket.io')

// 1. 建立HTTP服务器。
const server = http.createServer((req, res) => {

})

server.listen(8080)

// 2. 建立WebSocket,让socket.io监听HTTP服务器,一旦发现是WebSocket请求,则会自动进行处理。
const ws = io.listen(server)

// 建立连接完成后,触发connection事件。
// 该事件会返回一个socket对象(https://socket.io/docs/server-api/#Socket),可以利用socket对象进行发送、接收数据操作。
ws.on('connection', (socket) => {
  // 根据事件名,向客户端发送数据,数据数量不限。
  socket.emit('msg', '服务端向客户端发送数据第一条', '服务端向客户端发送数据第二条')

  // 根据事件名接收客户端返回的数据
  socket.on('msg', (...msgs) => {
    console.log(msgs)
  })

  // 使用计时器向客户端发送数据
  setInterval(() => {
    socket.emit('timer', new Date().getTime())
  }, 500);
})

客户端示例代码:/lesson19/index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <!-- 引用Socket.io的客户端js文件,由于Socket.io已在服务端监听了HTTP服务器的请求,一旦收到对该文件的请求,则会自动返回该文件,不需要开发人员配置。 -->
  <!-- 该文件在服务端的位置为/node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js -->
  <script src="http://localhost:8080/socket.io/socket.io.js"></script>
  <script>
    // 与服务器建立WebSocket连接,该连接为ws协议,socket.io不需要担心跨域问题。
    const socket = io.connect('ws://localhost:8080/')

    // 根据事件名,向服务端发送数据,数据数量不限。
    socket.emit('msg', '客户端向服务端发送数据第一条', '客户端向服务端发送数据第二条')

    // 根据事件名接收服务端返回的数据
    socket.on('msg', (...msgs) => {
      console.log(msgs)
    })

    // 接收服务端通过计时器发送来的数据
    socket.on('timer', (time) => {
      console.log(time)
    })
  </script>
</body>

</html>

用浏览器打开index.html,即可在控制台看到打印的消息。