WebSocket 实战:构建实时通信应用

WebSocket 实战:构建实时通信应用

什么是 WebSocket?

WebSocket 是一种在单个 TCP 连接上提供全双工通信的协议,允许服务器主动向客户端推送数据。

WebSocket vs HTTP

特性 HTTP WebSocket
连接方式 单向请求-响应 双向持久连接
数据推送 客户端主动请求 服务器主动推送
开销 每次请求都有开销 仅初始握手
延迟 较高 低延迟

WebSocket 基础使用

客户端实现

javascript 复制代码
const ws = new WebSocket('wss://example.com/ws');

ws.onopen = () => {
  console.log('连接已建立');
  ws.send('Hello Server!');
};

ws.onmessage = (event) => {
  console.log('收到消息:', event.data);
};

ws.onerror = (error) => {
  console.error('连接错误:', error);
};

ws.onclose = (event) => {
  console.log('连接关闭:', event.code, event.reason);
};

服务端实现(Node.js)

javascript 复制代码
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws) => {
  console.log('新客户端连接');
  
  ws.on('message', (message) => {
    console.log('收到消息:', message.toString());
    ws.send('收到你的消息: ' + message);
  });
  
  ws.on('close', () => {
    console.log('客户端断开连接');
  });
});

实时聊天应用

服务端

javascript 复制代码
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

const clients = new Set();

wss.on('connection', (ws) => {
  clients.add(ws);
  
  ws.on('message', (data) => {
    const message = JSON.parse(data);
    
    clients.forEach((client) => {
      if (client !== ws && client.readyState === WebSocket.OPEN) {
        client.send(JSON.stringify(message));
      }
    });
  });
  
  ws.on('close', () => {
    clients.delete(ws);
  });
});

客户端

javascript 复制代码
const ws = new WebSocket('ws://localhost:8080');
const messages = document.getElementById('messages');
const input = document.getElementById('input');

function sendMessage() {
  const message = {
    user: '当前用户',
    text: input.value,
    timestamp: new Date().toLocaleTimeString()
  };
  
  ws.send(JSON.stringify(message));
  input.value = '';
}

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  const div = document.createElement('div');
  div.innerHTML = `<strong>${message.user}</strong> ${message.timestamp}: ${message.text}`;
  messages.appendChild(div);
};

心跳机制

javascript 复制代码
// 服务端
wss.on('connection', (ws) => {
  const heartbeatInterval = setInterval(() => {
    if (ws.readyState === WebSocket.OPEN) {
      ws.ping();
    }
  }, 30000);
  
  ws.on('close', () => {
    clearInterval(heartbeatInterval);
  });
});

// 客户端
ws.on('ping', () => {
  ws.pong();
});

错误处理与重连

javascript 复制代码
function connect() {
  const ws = new WebSocket('ws://localhost:8080');
  
  ws.onclose = (event) => {
    console.log('连接关闭,正在重连...');
    setTimeout(connect, 5000);
  };
  
  ws.onerror = (error) => {
    console.error('连接错误:', error);
  };
  
  return ws;
}

const ws = connect();

使用 Socket.io

服务端

javascript 复制代码
const io = require('socket.io')(3000);

io.on('connection', (socket) => {
  console.log('新连接:', socket.id);
  
  socket.on('chat message', (msg) => {
    io.emit('chat message', msg);
  });
  
  socket.on('disconnect', () => {
    console.log('断开连接:', socket.id);
  });
});

客户端

javascript 复制代码
const socket = io('http://localhost:3000');

socket.on('chat message', (msg) => {
  console.log('收到消息:', msg);
});

socket.emit('chat message', 'Hello Server');

房间功能

javascript 复制代码
// 服务端
io.on('connection', (socket) => {
  socket.join('room1');
  
  io.to('room1').emit('message', '新用户加入房间');
  
  socket.on('send to room', (msg) => {
    io.to('room1').emit('room message', msg);
  });
});

WebSocket 安全

使用 HTTPS/WSS

javascript 复制代码
const https = require('https');
const fs = require('fs');
const WebSocket = require('ws');

const server = https.createServer({
  cert: fs.readFileSync('cert.pem'),
  key: fs.readFileSync('key.pem')
});

const wss = new WebSocket.Server({ server });

认证机制

javascript 复制代码
wss.on('connection', (ws, req) => {
  const token = req.headers['sec-websocket-protocol'];
  
  if (!validateToken(token)) {
    ws.close(1008, 'Unauthorized');
    return;
  }
});

总结

WebSocket 为实时应用提供了强大的基础:

  1. 低延迟通信:适合实时聊天、游戏等场景
  2. 双向通信:服务器可以主动推送数据
  3. 持久连接:减少连接开销

通过合理的错误处理和重连机制,可以构建稳定可靠的实时应用。

相关推荐
老金带你玩AI9 小时前
ChatGPT dots,到底能替你操多少心?
人工智能
养肥胖虎9 小时前
CodeGraph学习笔记:给代码建索引,节省Token和时间
ai·codegraph·代码索引
AliCloudROS10 小时前
计算巢 X DeepSeek Harness — 云端智能体工作台
人工智能·阿里云
深蓝AI10 小时前
GitHub的Push一年涨4.9倍:AI Agent为什么逼它重做Git存储?
人工智能·github
stereohomology10 小时前
大模型的观点谨:StoryTold 「Crafting Apps」四件套 · 深度总览
人工智能·llm
运维行者_10 小时前
网络性能监控怎么做?从自动发现到根因分析的4个环节
运维·服务器·网络·人工智能·支持向量机
Su米苏11 小时前
Spring AI 中MCP 与普通 @Tool的区别
java·人工智能·spring
美狐美颜sdk11 小时前
直播APP源码可以直接接入视频美颜sdk吗?技术方案详解
android·人工智能·音视频·美颜sdk·直播美颜sdk
问商十三载11 小时前
AI引擎生成式优化实践:刑事辩护律师团队IP构建
大数据·人工智能