🎯 实战进阶:用 WebSocket 打造一个实时聊天室

3 阅读2分钟

太棒了!👏 你已经掌握了 Node.js 基础,现在我们来做一个更酷的项目 ——


📌 目标
搭建一个支持多用户在线、实时发送消息的网页聊天室,使用:

  • Node.js + Express → 提供网页和 API
  • Socket.IO → 实现双向实时通信(WebSocket 封装)

最终效果:
👉 多个浏览器打开,一人发消息,所有人立刻看到!


🧱 第一步:项目结构

chatroom/
├── public/
│   └── index.html        ← 聊天页面
├── server.js             ← 后端服务器
├── package.json

✅ 第二步:初始化项目

mkdir chatroom
cd chatroom
npm init -y
npm install express socket.io

socket.io 是最流行的实时通信库,自动降级兼容不支持 WebSocket 的浏览器。


✅ 第三步:创建 server.js

// server.js
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');

// 创建 Express 应用
const app = express();
const server = http.createServer(app);
const io = socketIo(server); // 把 Socket.IO 绑定到 HTTP 服务器

// 提供静态文件
app.use(express.static('public'));

// 监听连接事件
io.on('connection', (socket) => {
  console.log('🎉 新用户连接:', socket.id);

  // 接收客户端发来的聊天消息
  socket.on('chat message', (msg) => {
    console.log('📨 收到消息:', msg);

    // 广播给所有连接的用户(包括自己)
    io.emit('chat message', {
      message: msg,
      id: socket.id.slice(0, 5), // 简化 ID 显示
      timestamp: new Date().toLocaleTimeString()
    });
  });

  // 用户断开连接
  socket.on('disconnect', () => {
    console.log('👋 用户断开:', socket.id);
  });
});

// 启动服务器
const PORT = 3000;
server.listen(PORT, () => {
  console.log(`✅ 聊天室已启动:http://localhost:${PORT}`);
});

✅ 第四步:创建前端页面 public/index.html

<!DOCTYPE html>
<html>
<head>
  <title>💬 实时聊天室</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      max-width: 600px;
      margin: 40px auto;
      padding: 20px;
    }
    #messages {
      height: 400px;
      border: 1px solid #ddd;
      padding: 10px;
      overflow-y: scroll;
      margin-bottom: 10px;
      background: #f9f9f9;
    }
    .message {
      padding: 8px;
      margin: 5px 0;
      background: #e3f2fd;
      border-radius: 5px;
      font-size: 14px;
    }
    .meta {
      color: #666;
      font-size: 12px;
    }
    input, button {
      padding: 10px;
      font-size: 16px;
    }
    #inputMessage {
      width: 70%;
    }
    button {
      width: 28%;
      background: #1976d2;
      color: white;
      border: none;
      cursor: pointer;
    }
  </style>
</head>
<body>

  <h1>💬 实时聊天室</h1>
  <p>当前连接 ID: <strong id="userId"></strong></p>
  <div id="messages"></div>
  <input type="text" id="inputMessage" placeholder="输入消息..." />
  <button onclick="sendMessage()">发送</button>
  <!-- 引入 Socket.IO 客户端库 -->
  <script src="/socket.io/socket.io.js"></script>
  <script>
    // 连接到服务器
    const socket = io();

    // 显示自己的连接 ID
    document.getElementById('userId').textContent = socket.id;

    // 监听收到的消息
    socket.on('chat message', (data) => {
      const messages = document.getElementById('messages');

      const el = document.createElement('div');
      el.className = 'message';
      el.innerHTML = `
        <div><strong>[${data.id}]</strong>: ${data.message}</div>
        <div class="meta">${data.timestamp}</div>
      `;

      messages.appendChild(el);
      messages.scrollTop = messages.scrollHeight; // 滚动到底部
    });

    // 发送消息函数
    function sendMessage() {
      const input = document.getElementById('inputMessage');
      const value = input.value.trim();
      if (value) {
        socket.emit('chat message', value); // 发送给服务器
        input.value = ''; // 清空输入框
      }
    }

    // 支持回车发送
    document.getElementById('inputMessage').addEventListener('keypress', (e) => {
      if (e.key === 'Enter') {
        sendMessage();
      }
    });
  </script>
</body>
</html>

🏃‍♂️ 第五步:运行并测试

1. 启动服务器

node server.js

输出:

✅ 聊天室已启动:http://localhost:3000

2. 打开多个浏览器窗口测试

分别访问:
👉 http://localhost:3000

3. 开始聊天!

在一个窗口输入消息并发送,其他所有窗口会立刻同步显示

🎉 实时聊天室成功啦!


🔍 核心原理讲解

概念说明
io.on('connection')监听新用户连接
socket.emit('event', data)向某个客户端发送事件
io.emit('event', data)所有连接的客户端广播
socket.on('event', fn)客户端监听服务器事件
双向通信不再是“请求-响应”,而是“随时互发消息”

✅ 小结一句话:

使用 Express + Socket.IO,你可以轻松实现一个支持多用户实时通信的聊天室,这是 Web 实时应用的核心技术。


💡 下一步可以加的功能

功能如何实现
用户昵称输入昵称后带上名字发消息
在线人数io.engine.clientsCount 显示
私聊功能socket.to(id).emit()
消息存储存到数组或数据库中,重启不丢
房间系统socket.join('room1') 加入房间

继续深入比如:

  • “教我加用户名功能”
  • “如何保存历史消息?”
  • “用 MongoDB 存聊天记录”