多帐号聊天项目设计
该项目是用Vue实现的一个多帐号多对象的聊天室项目,初期希望的是划分组件的同时可以将逻辑也进行划分,通过这样的方式来减小每个组件的复杂度。但是后来发现几乎所有的逻辑,都是围绕着从服务端拉取到的消息来进行的,如果强行分割逻辑,只会增加代码的复杂度。
组件划分
- Wrap
- UserList
- RoomList
- ChatWindow
- MessageItem
- EmoticonSelector
这里将组件划分为用户列表UserList、聊天列表RoomList、聊天窗口ChatWindow。
组件参数及事件
UserList
Props:
- users:帐号
- current:当前帐号
- unreadInfo:用于展示未读标记
Events:
- changeUser:切换用户
RoomList
Props:
- rooms:聊天室
- current:当前聊天室
- roomsInfo:聊天室未读数、开始时间、最新时间、最新消息、状态等
Events:
- changeRoom
EmoticonSelector
Props:
- emoticons
Events:
- select
MessageItem
Props:
- user:当前帐号
- other:聊天对象
- message:消息
- roomStatus:聊天室状态*
Events:
ChatWindow
Props:
- user:当前帐号
- room:当前聊天室
- messages:当前聊天室消息
- roomsInfo:聊天室未读数、开始时间、最新时间、分数、最新消息、状态
Events:
- send:发送消息
基本设计思路
行为一:获取到消息(我们的后端拉取消息是根据帐号拉取的)
Wrap
中不停(标记messagePolling
)拉取每个帐号(activeActors
)消息messages
- =>
messages
根据roomId
保存localStorage
- => 存在
roomId
不在房间(roomIds
)中 => 拉取该用户rooms
* - =>
messages
中有当前帐号(currActor
)的消息 => 重新排列聊天室(roomList
)* - =>
messages
中有当前聊天室(currRoom
)的消息 => 重新计算当前聊天室消息(messageList
) - => 计算房间未读等信息(
roomsInfo
) - => 计算帐号未读信息(
unreadByActor
)
行为二:发送消息
ChatWindow
触发send
- => 将消息保存到localStorage中
- => 重新设置当前聊天室消息(
messageList
) - => 重新排列聊天室(
roomList
)
行为三:切换帐号
UserList
触发changeUser
- => 重新计算聊天室(
roomList
)通过(rooms
)和(currActor
) => 重新排列聊天室(roomList
)* => 重新设置当前聊天室(currRoom
) => 重新设置当前聊天消息(messageList
) - => 计算房间未读等信息(
roomsInfo
) - => 计算帐号未读信息(
unreadByActor
)
在实际代码中,计算unreadByActor
依赖roomsInfo
;计算messageList
,依赖将消息保存localStorage。
值得一提
async/await
“同时”请求:通过await Promise.all
可以将请求异步,后面的代码继续同步执行,需要注意的是Promise.all
中的promise
需要自己处理自己的异常,这样来避免异常提早将Promise.all
拒绝。