WebSocket简易聊天室实现

130 阅读4分钟

WebSocket简易聊天室实现

目录

项目目录结构

chat-app/
├── client/                 # 前端项目目录
│   ├── src/
│   │   ├── App.vue        # 主组件
│   │   └── main.js        # 入口文件
│   ├── package.json
│   └── vite.config.js
│
├── server/                 # 后端项目目录
│   ├── server.js          # WebSocket服务器
│   └── package.json
│
└── README.md              # 项目文档

项目概述

这是一个基于WebSocket的实时聊天室应用,使用Vue 3作为前端框架,Node.js + Express作为后端服务器,实现了基本的即时通讯功能。

技术栈

  • 前端:Vue 3 + Vite
  • 后端:Node.js + Express + ws
  • 开发工具:VS Code
  • 包管理:npm/yarn

实现步骤

1. 项目初始化

1.1 创建项目结构
mkdir chat-app
cd chat-app

# 创建客户端
npm create vite@latest client -- --template vue
cd client
npm install

# 创建服务器端
mkdir server
cd server
npm init -y
1.2 安装依赖

客户端依赖:

cd client
npm install vue@latest

服务器端依赖:

cd server
npm install express ws cors

2. 服务器端实现

2.1 创建WebSocket服务器 (server/server.js)
const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const cors = require('cors');

const app = express();
app.use(cors());

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

// 存储所有连接的客户端
const clients = new Set();

// WebSocket连接处理
wss.on('connection', (ws) => {
  clients.add(ws);
  
  // 发送欢迎消息
  ws.send(JSON.stringify({
    type: 'system',
    content: '欢迎加入聊天室!',
    timestamp: Date.now()
  }));

  // 更新在线人数
  updateOnlineCount();

  // 处理消息
  ws.on('message', (message) => {
    try {
      const data = JSON.parse(message);
      if (data.type === 'chat') {
        broadcast({
          type: 'chat',
          content: data.content,
          userId: data.userId,
          timestamp: data.timestamp || Date.now()
        });
      }
    } catch (e) {
      console.error('消息解析错误:', e);
    }
  });

  // 处理断开连接
  ws.on('close', () => {
    clients.delete(ws);
    updateOnlineCount();
  });
});

// 广播消息
function broadcast(data) {
  const message = JSON.stringify(data);
  clients.forEach(client => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(message);
    }
  });
}

// 更新在线人数
function updateOnlineCount() {
  broadcast({
    type: 'online_count',
    count: clients.size
  });
}

const PORT = 3456;
server.listen(PORT, () => {
  console.log(`服务器运行在端口 ${PORT}`);
});

3. 前端实现

3.1 创建聊天室组件 (client/src/App.vue)
<template>
  <div class="chat-app">
    <div class="chat-container">
      <!-- 头部 -->
      <div class="chat-header">
        <h1>WebSocket 聊天室</h1>
        <div class="online-count">在线人数: {{ onlineCount }}</div>
      </div>
      
      <!-- 消息区域 -->
      <div class="chat-messages" ref="messagesContainer">
        <div v-for="message in messages" 
             :class="['message-wrapper', message.type === 'system' ? 'system' : (message.isSelf ? 'self' : 'other')]">
          <!-- 消息内容 -->
          <div class="message-content-wrapper">
            <div class="message-bubble">{{ message.content }}</div>
            <div class="message-info">
              <span class="user-id">{{ getUserIdShort(message.userId) }}</span>
              <span class="message-time">{{ formatTime(message.timestamp) }}</span>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 输入区域 -->
      <div class="chat-input">
        <input v-model="newMessage" 
               @keyup.enter="sendMessage"
               placeholder="输入消息...">
        <button @click="sendMessage">发送</button>
      </div>
    </div>
  </div>
</template>

4. 样式设计

4.1 基础样式
.chat-app {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f0f2f5;
}

.chat-container {
  width: 100%;
  max-width: 800px;
  height: 100vh;
  background-color: white;
  display: flex;
  flex-direction: column;
}
4.2 消息气泡样式
.message-bubble {
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 14px;
  word-break: break-word;
}

.self .message-bubble {
  background-color: #95ec69;
  border-radius: 8px;
  border-top-right-radius: 4px;
}

.other .message-bubble {
  background-color: #fff;
  border-radius: 8px;
  border-top-left-radius: 4px;
}

5. 功能实现

5.1 WebSocket连接管理
const ws = ref(null);
const isConnected = ref(false);

function connectWebSocket() {
  ws.value = new WebSocket('ws://localhost:3456');
  
  ws.value.onopen = () => {
    isConnected.value = true;
  };
  
  ws.value.onclose = () => {
    isConnected.value = false;
    setTimeout(connectWebSocket, 3000); // 自动重连
  };
}
5.2 消息处理
ws.value.onmessage = (event) => {
  const data = JSON.parse(event.data);
  
  if (data.type === 'online_count') {
    onlineCount.value = data.count;
    return;
  }
  
  messages.value.push({
    ...data,
    timestamp: new Date(),
    isSelf: data.userId === userId.value
  });
  scrollToBottom();
};

6. 部署说明

6.1 开发环境启动
# 启动服务器
cd server
npm install
node server.js

# 启动客户端
cd client
npm install
npm run dev
6.2 生产环境部署
# 构建前端
cd client
npm run build

# 启动服务器
cd ../server
node server.js

7. 注意事项

  1. 端口配置:

    • 服务器默认端口:3456
    • 确保端口未被占用
  2. 跨域处理:

    • 服务器端已配置CORS
    • 开发环境需要正确配置WebSocket地址
  3. 错误处理:

    • WebSocket断开自动重连
    • 消息发送失败处理
    • 数据格式验证

8. 扩展建议

  1. 功能扩展:

    • 用户认证
    • 私聊功能
    • 消息历史记录
    • 文件传输
    • 表情支持
  2. 性能优化:

    • 消息队列
    • 心跳检测
    • 消息压缩
    • 长连接优化
  3. 安全性:

    • 消息加密
    • XSS防护
    • 速率限制

9. 调试指南

  1. WebSocket连接:

    • 使用浏览器开发工具Network面板
    • 监控WebSocket连接状态
  2. 消息发送:

    • 检查消息格式
    • 验证时间戳
    • 确认用户ID
  3. 样式调试:

    • 使用Vue DevTools
    • 检查消息气泡布局
    • 验证响应式设计

结语

本文档详细介绍了如何从零开始实现一个基于WebSocket的聊天室应用。通过按步骤实现,可以构建一个功能完整的实时通讯系统。建议在开发过程中注意代码质量和错误处理,同时考虑后续的扩展性和维护性。