一个基于Vue3和WebSocket的简易网络聊天室项目,包括服务端和客户端部分。
项目地址 websocket-chat
下面是项目的主要组成部分和功能:
chat-websocket/
|-- server/ # WebSocket 服务端
| |-- run.js # 服务端
| |-- DBManager.js #数据库对象管理
|-- src/
| |-- components/
| | |-- ... # Vue 组件
| |-- assets/
| | |-- ... # 静态资源
| |-- views/
| | |-- Home.vue # 主要视图组件
| | |-- Login.vue # 登录视图组件
| |-- router/
| |-- App.vue
| |-- main.js
|-- public/
|-- README.md
|-- ...
前端框架: 使用 Vue3 作为前端框架,Element Plus 用于 UI 组件。
后端框架: 后端使用 Node.js + Mysql 实现,使用 WebSocket 库 ws 作为 WebSocket 服务端。
WebSocket: 实时通信使用 WebSocket 技术,保证消息的实时性。
上面是项目介绍,下面介绍细节
sessions[clientId]
,增加定时器定时清除session,用于24H过期机制.消息对象
,客户端和服务端共有相同的消息对象.一次简单的发送和获取消息的流程如图:
聊天室布局参考Element Plus提供的布局
其中头部展示用户信息状态, 左边是群组和用户选择, 主界面就是聊天界面,展示聊天信息.
最终成品如下:
一些细节解释
可以显示用户当前连接状态,当链接断开后,可以重新连接.
进入页面后已经建立websocket连接,单击登陆后发送请求,若成功则接收到username
,uid
,session_id
,这三个参数,直接以cookie的形式保存在本地.
后续进入页面,服务端都会 验证session,进行持久化访问.
每次单击群组或用户,根据当前选择发送请求获取接收不同类型消息
表名 | 列名 | 数据类型 | 说明 |
---|---|---|---|
USER | uid | INTEGER | 用户ID(主键,自增) |
name | VARCHAR(255) | 用户名 | |
password | VARCHAR(255) | 用户密码 | |
GROUPS | gid | INTEGER | 群组ID(主键,自增) |
name | VARCHAR(255) | 群组名 | |
GMESSAGE | id | INTEGER | 消息ID(主键,自增) |
gid | INTEGER | 群组ID | |
uid | INTEGER | 发送消息的用户ID | |
gname | VARCHAR(255) | 群组名 | |
text | TEXT | 消息内容 | |
UMESSAGE | id | INTEGER | 消息ID(主键,自增) |
s_uid | INTEGER | 发送消息的用户ID | |
r_uid | INTEGER | 接收消息的用户ID | |
text | TEXT | 消息内容 | |
time | TIMESTAMP | 消息发送时间 | |
GROUP_USER | uid | INTEGER | 用户ID |
gid | INTEGER | 群组ID |
各表分别继承管理类
这里使用 Promise 的方式可以更好地处理异步代码
导入所需的模块和类
entity.js
: 包含了用户和消息的实体类定义。DBManager.js
: 包含了与数据库交互的相关类。ws
: WebSocket 模块。常量和变量定义
初始化WebSocket服务器
消息处理
用户登录
sessions的保存形式如下:
sessions[clientId] = {
uid: uid,
username: msg.data.username,
ws: this,
creationTime: Date.now(),
sessionID: clientId,
};
定时器判断是否过期
孟宁老师上课旁征博引,时不时与同学们互动 (指让同学们发数字),无论是前端网络编程,网络协议RPC,还是Linux内核网络协议栈,似乎都信手拈来,相信如果认真听课,加上自己的钻研,绝对受益匪浅.
对于这门课程,完全可以说是师傅领进门,修行看个人了,我们深入其中某个方向,也会有所建树.
此前只是接触过JS和Vue,并未熟练掌握它们,这次由于课程原因,尝试完全使用JS作为前后端代码,没有使用熟悉的Python和Java来构建后端,算是对自己的一次挑战.幸好有chatgpt在细节上的协助,结合各类组件丰富的文档,完成了这次项目.