聊天场景
- 所有人都在同一个群中聊天
- 只有一个人发送消息,在线的所有人都能收到(核心)
- 针对离线的人(注册过,但是没有登录的人),等他再次登录,补发没有看到过的历史消息
- 首次注册的人,看不到之前的消息
深入场景
- 我们需要一个在线用户管理机制(记录当前所有在线用户信息),可以同时动态的、正确的维护该信息
(1)有人登录,添加到在线列表
(2)有人登出,踢出在线列表 - 一个人发送消息的数据流转流程:
(1)前端获取用户要发布的消息
(2)通过websocket,将消息推送给服务端
(3)后端遍历所有当前在线用户,通过websocket挨个发送消息
库表信息
用户表:uid,username,nickname,password,上次登出时间(注册用户时,上次登陆时间记为null)
消息表:mid,uid,context,发送时间
聊天室主要结构
只要建立一个websocket链接,就会生成一个endpoint对象,用来维护在线用户信息
每发送一条消息,找到所有在线用户,把所有消息发出去;并且要经过messageDao层,把信息把存到mysql中
只要上线,就会把在线用户信息维护起来(记录当前在线用户情况),然后在messageDao层中查询所有历史消息,发送给上线的这个用户
下线,首先要在用户列表中删除掉该用户,然后把本次下线的时间记录在数据库中,然后在下次上线时才可以根据下线时间,以及查询到的历史消息时间,可以查询到它的历史消息
WebSocket中事件驱动的上如何做到处理
用户上线、用户下线、发送消息三种不同业务事件
onOpen、onClose、 onMessage 三种不同的websocket
-
处理用户上线逻辑
1. 判断上线的是哪个用户
从HttpSession中获取当前登录用户的信息
这个Session不是HttpSession
这里的Sesion实际上值得是WebSocket Session
2. 记录该用户到在线用户列表中(如果重复上线,把之前的踢下线)
3. 查找历史信息并发送 -
处理用户下线逻辑
1. 记录当前用户下线时间
当前用户从哪里获取?
我们当前无法获取该信息,需提前保存该信息
2. 从在线用户列表中踢出当前用户 -
处理收到用户发来的消息的逻辑
1. 记录消息
是当前用户发的消息,发的内容是什么
2. 把消息转发给所有在线用户