一个使用 Go 语言开发的多房间实时聊天应用,支持用户注册/登录、房间切换、聊天历史记录等功能。
📸 项目演示
登录界面

多人实时聊天


✨ 功能特点
- ✅ 用户注册/登录 - 支持用户名和密码注册,密码安全存储
- ✅ 多房间聊天 - 支持切换不同的聊天房间
- ✅ 实时消息 - 基于 WebSocket 的实时消息推送
- ✅ 在线用户列表 - 显示当前房间的在线用户
- ✅ 聊天历史记录 - 使用 SQLite 持久化存储聊天记录
- ✅ 系统通知 - 用户加入/离开房间的系统提示
- ✅ 登录状态保持 - 刷新页面后自动保持登录状态
- ✅ 密码验证 - 用户名和密码长度限制
- ✅ 精美的 UI 设计 - 渐变色主题,流畅的交互体验
🛠️ 技术栈
后端
- Go 语言 - 高性能的服务端编程语言
- Gin 框架 - 轻量级的 HTTP Web 框架
- Gorilla WebSocket - WebSocket 通信库
- SQLite - 轻量级关系型数据库
- modernc.org/sqlite - SQLite 驱动(纯 Go 实现,无需 CGO)
前端
- HTML5 + CSS3 - 现代网页标准
- Vanilla JavaScript - 原生 JS,无需框架
- LocalStorage - 浏览器本地状态存储
📁 项目结构
GoCloud/
├── cmd/
│ └── server/
│ └── main.go # 主程序入口,包含前端页面
├── internal/
│ ├── chat/
│ │ ├── types.go # 数据结构定义
│ │ ├── hub.go # 核心逻辑:房间管理、消息广播
│ │ └── client.go # WebSocket 客户端处理
│ ├── handler/
│ │ └── websocket.go # HTTP API 处理器
│ └── database/
│ ├── database.go # 数据库初始化
│ ├── user.go # 用户数据库操作
│ ├── room.go # 房间数据库操作
│ └── message.go # 消息数据库操作
├── go.mod # Go 模块文件
├── go.sum # 依赖锁定文件
├── chat.db # SQLite 数据库文件(运行时生成)
└── README.md # 项目说明文档
🚀 快速开始
前置要求
- Go 1.16 或更高版本
安装依赖
bash
go mod download
运行项目
bash
go run cmd/server/main.go
服务器将在 http://localhost:8080 启动。
使用说明
- 打开浏览器访问
http://localhost:8080 - 点击「注册」创建新账号
- 输入用户名(3-20字符)和密码(6-20字符)
- 登录后进入聊天界面
- 在左侧选择不同的聊天房间
- 在底部输入框输入消息并发送
🗄️ 数据库设计
users 表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | TEXT | 用户ID(UUID) |
| username | TEXT | 用户名(唯一) |
| password | TEXT | 密码(哈希存储) |
| created_at | DATETIME | 创建时间 |
rooms 表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | TEXT | 房间ID |
| name | TEXT | 房间名称 |
| description | TEXT | 房间描述 |
| created_at | DATETIME | 创建时间 |
messages 表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | INTEGER | 消息ID(自增) |
| room_id | TEXT | 房间ID |
| user_id | TEXT | 用户ID |
| username | TEXT | 用户名 |
| type | TEXT | 消息类型(message/system) |
| content | TEXT | 消息内容 |
| time | TEXT | 时间戳 |
| created_at | DATETIME | 创建时间 |
📡 WebSocket 消息格式
消息类型
1. 用户加入房间
json
{
"type": "join",
"roomId": "general",
"fromId": "user-uuid",
"fromName": "username",
"content": "加入了房间",
"time": "2026-06-03T16:00:00Z"
}
2. 用户离开房间
json
{
"type": "leave",
"roomId": "general",
"fromId": "user-uuid",
"fromName": "username",
"content": "离开了房间",
"time": "2026-06-03T16:00:00Z"
}
3. 普通消息
json
{
"type": "message",
"roomId": "general",
"fromId": "user-uuid",
"fromName": "username",
"content": "Hello, World!",
"time": "2026-06-03T16:00:00Z"
}
4. 在线用户列表
json
{
"type": "users",
"roomId": "general",
"users": ["user1", "user2", "user3"]
}
5. 切换房间
json
{
"type": "change_room",
"roomId": "tech"
}
🔌 HTTP API
1. 用户注册
POST /api/register
Content-Type: application/json
{
"username": "testuser",
"password": "123456"
}
响应:
{
"success": true,
"user": {
"id": "user-uuid",
"username": "testuser"
}
}
2. 用户登录
POST /api/login
Content-Type: application/json
{
"username": "testuser",
"password": "123456"
}
响应:
{
"success": true,
"user": {
"id": "user-uuid",
"username": "testuser"
}
}
3. 获取房间列表
GET /api/rooms
响应:
{
"success": true,
"rooms": [
{
"id": "general",
"name": "大厅",
"description": "欢迎来到大厅,大家可以在这里畅聊!"
},
{
"id": "tech",
"name": "技术交流",
"description": "讨论技术问题、分享经验"
},
{
"id": "game",
"name": "游戏频道",
"description": "一起聊游戏,找队友"
}
]
}
4. WebSocket 连接
GET /ws?userId={userId}&username={username}&roomId={roomId}
💡 核心实现
Hub 模式
使用经典的 Hub 模式管理 WebSocket 连接:
- Hub:中心管理器,负责管理所有房间和客户端
- Room:房间,包含在线客户端和房间信息
- Client:客户端连接,处理单个用户的 WebSocket 通信
消息广播流程
- 客户端发送消息到 Hub 的 Broadcast channel
- Hub 根据消息的 RoomID 找到对应房间
- Hub 将消息发送给房间内的所有客户端
- 同时将消息保存到 SQLite 数据库
数据持久化
- 使用 SQLite 数据库存储用户、房间和消息
- 用户加入房间时从数据库加载历史消息
- 新消息实时保存到数据库
📝 开发历程
主要问题解决
- 在线用户列表不同步 - 修复了用户列表的广播逻辑,确保所有客户端都能收到更新
- 消息显示不一致 - 调整消息发送顺序,优先发送用户列表,确保消息顺序正确
- 刷新页面状态丢失 - 使用 LocalStorage 保存登录状态和房间信息
- 数据不持久化 - 集成 SQLite 数据库,实现用户和消息的永久存储
- WebSocket 消息拼接问题 - 修复 WritePump 消息发送逻辑,每条消息单独发送
优化改进
- 调整消息发送顺序,优先发送用户列表
- 添加更完善的错误处理和日志记录
- 实现房间状态的保存和恢复
- 优化 UI 设计,使用渐变色主题
🔮 未来优化方向
- 添加头像支持
- 支持私聊功能
- 添加消息已读状态
- 支持图片/文件发送
- 添加消息搜索功能
- 实现用户权限管理
- 添加房间创建/删除功能
- 支持消息撤回
- 添加表情支持
- 实现消息推送通知
注意:这是一个学习项目,用于演示 Go 语言 WebSocket 开发。生产环境使用时请加强安全措施。
完整源码:
如果觉得这个项目对你有帮助,欢迎点赞 👍、收藏 ⭐、关注 👀!