MST

星途 面试题库

面试题:网络编程之Node.js与WebSocket复杂场景设计

设计一个基于Node.js与WebSocket的实时多人协作绘图应用,要求支持多用户同时绘制图形、实时同步图形变化、处理网络延迟和丢包等问题,并描述应用的整体架构和关键技术点。
29.0万 热度难度
后端开发网络编程

知识考点

AI 面试

面试题答案

一键面试

整体架构

  1. 客户端
    • 用户界面:使用HTML5的Canvas元素来绘制图形。用户通过鼠标或触摸事件在Canvas上进行绘图操作。
    • WebSocket连接:通过wsws - client等库建立与服务器的WebSocket连接,将绘图操作(如绘制线条的起点、终点坐标等)发送到服务器,并接收服务器广播的其他用户的绘图操作,实时更新本地Canvas。
  2. 服务器端
    • Node.js服务器:使用http模块或更便捷的express框架搭建HTTP服务器,同时使用ws模块创建WebSocket服务器。
    • 连接管理:维护一个连接池,记录所有连接到服务器的WebSocket客户端。当有新用户连接时,将其加入连接池;用户断开连接时,从连接池中移除。
    • 消息处理:接收客户端发送的绘图操作消息,然后将这些消息广播给除发送者之外的其他所有客户端,实现实时同步。

关键技术点

  1. WebSocket
    • 建立连接:在客户端使用new WebSocket(url)建立与服务器的连接,服务器端使用ws.Server监听特定端口。例如:
      // 客户端
      const socket = new WebSocket('ws://localhost:8080');
      // 服务器端
      const WebSocket = require('ws');
      const wss = new WebSocket.Server({ port: 8080 });
      
    • 消息发送与接收:客户端使用socket.send(data)发送消息,通过socket.on('message', function (data) {... })接收消息;服务器端使用ws.send(data)向单个客户端发送消息,通过ws.on('message', function (data) {... })接收客户端消息。
  2. 绘图操作处理
    • 在客户端:监听Canvas的mousedownmousemovemouseup等事件,记录绘图的起始点、移动轨迹和结束点等信息,将这些信息封装成消息格式(如JSON)发送给服务器。例如:
      canvas.addEventListener('mousedown', function (e) {
        startX = e.offsetX;
        startY = e.offsetY;
      });
      canvas.addEventListener('mousemove', function (e) {
        if (isDrawing) {
          const message = {
            type: 'drawLine',
            startX: startX,
            startY: startY,
            endX: e.offsetX,
            endY: e.offsetY
          };
          socket.send(JSON.stringify(message));
          startX = e.offsetX;
          startY = e.offsetY;
        }
      });
      canvas.addEventListener('mouseup', function () {
        isDrawing = false;
      });
      
    • 在服务器端:接收到客户端发送的绘图消息后,将其广播给其他客户端。例如:
      wss.on('connection', function connection(ws) {
        ws.on('message', function incoming(message) {
          wss.clients.forEach(function each(client) {
            if (client!== ws && client.readyState === WebSocket.OPEN) {
              client.send(message);
            }
          });
        });
      });
      
  3. 处理网络延迟和丢包
    • 心跳机制:客户端和服务器端定期发送心跳消息(如每10秒一次),以检测连接是否正常。如果服务器端在一定时间内(如30秒)未收到客户端的心跳消息,则认为客户端已断开连接,将其从连接池中移除。
    • 消息重传:客户端在发送消息后启动一个定时器,如果在一定时间内(如500毫秒)未收到服务器的确认消息,则重新发送该消息。服务器端在收到重复消息时,应进行去重处理,避免重复绘制。
    • 缓冲机制:在客户端设置一个消息缓冲区,当网络延迟较高时,先将绘图操作消息缓存在本地,待网络恢复正常后再批量发送给服务器,减少丢包影响。在服务器端也可以设置类似的缓冲区,对广播消息进行缓冲处理,确保消息按顺序发送给客户端。