Web在线聊天室 --- 详细设计
Posted 满眼*星辰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Web在线聊天室 --- 详细设计相关的知识,希望对你有一定的参考价值。
详细设计
1. WebSocket
1.1 举例WebSocket应用
业务背景:张三要发送消息给李四
实现:
(1)客户端点到点发送消息
(2)服务端转发消息(我们采取这种方式)
流程:
- 张三发送消息给服务端
- 服务端发送消息给李四
这种是基于http协议的与服务端建立连接相互请求和响应
这种方式用http去实现是不行的
- 因为http是短连接,无状态的,一次请求完了服务器一次响应后就会断开连接。
- 服务器端的 ip 是开放在公网的,所有人能访问;而客户端的 ip 是不开放的(服务端不知道),所以服务器端不能主动给客户端发送消息
我们会采取这种服务器转发消息方式来实现消息发送。
我们这里用到 webSocket 技术
1.2 webSocket 实现的消息推送流程
(1)客户端和服务器端建立连接,只能客户端发起请求,然后双方建立连接(长连接)
客户端 js 代码:
websocket = new WebSocket("ws://localhost:8080/java_chatroom/test/1");
双方建立连接后:事件驱动的异步函数回调
(2)双方通信都是全双工的,客户端和服务端都可以主动的收发消息
客户端发消息:websocket.send(message)
服务端发消息:session.getBasicRemote().sendText(message)
这里的Session对象用来保持会话的,这是建立连接之后,就有的会话对象,只要我们有session引用,就可以发消息。
注意事项:session会话,是WebSocket的会话(长连接没关闭就是一个会话),和Servlet的session是不一样的
双方接收消息:被动接收(事件驱动的异步回调)
1.3 整个流程涉及到的主要代码
目前项目中,业务是需要把张三发送的消息转发到所有的客户端中,这里是由前端去过去某个消息频道的消息
前端保存有所有接收的消息,用户进入某个频道后,在接收的消息列表中,过滤并显示
张三的消息 + 渠道A —》发送到所有客户端 —》 李四在渠道C,接收到的消息,过滤只显示C渠道
2. 详细设计
2.1 前后端接口流程
用户相关接口:
- 注册
- 登录:输入账号密码,点击登录按钮后,调用的接口
- 检查是否已登录:页面初始化后,调用接口
分析以上接口和页面的执行流程(关联关系)
以上业务,客户端接收消息有两个场景:
- 上次登录之后 —》 数据库查询(发送的消息要保存在数据库)
–》服务端建立连接事件 - 新的消息 --》 服务端接收消息事件中
–》所有客户端转发消息
需要考虑:服务端在什么时候代码进行发送,客户端在什么地方接收
消息在服务端什么地方保存
2.2 前后端接口设计
2.2.1 用户管理
注册:
请求:
POST /register
{
name: xxx,
password: xxx,
nickName: "蔡徐坤",
signature: "我擅长唱跳rap篮球",
}
响应:
HTTP/1.1 200 OK
{
ok: true,
reason: xxx
}
登录:
请求:
POST /login
{
name: xxx,
password: xxx
}
响应:
HTTP/1.1 200 OK
{
ok: true,
reason: xxx,
userId: xxx,
name: xxx,
nickName: xxx,
signature: xxx
}
检测登陆状态:
请求:
GET /login
响应:
HTTP/1.1 200 OK
{
ok: true,
userId: xxx,
name: xxx,
nickName: xxx,
signature: xxx
}
注销:
请求:
GET /logout
响应:
HTTP/1.1 200 OK
{
ok: true,
reason: xxx
}
2.2.2 频道管理
新增频道:
请求:
POST /channel
{
channelName: xxx
}
响应:
HTTP/1.1 200 OK
{
ok: true,
reason: xxx
}
查找频道信息:
请求:
GET /channel
响应:
HTTP/1.1 200 OK
[
{
channelId: 1,
channelName: xxx
},
{
channelId: 2,
channelName: xxx
}
]
删除频道信息:
请求:
DELETE /channel?channelId=xxx
响应:
HTTP/1.1 200 OK
{
ok: true,
reason: xxx
}
2.2.3 消息管理
建立连接:
请求:
ws://[ip]:[port]/message/{userId}
发送/接收消息格式:
{
"userId": 1,
"nickName": "蔡徐坤",
"channelId": 1,
"content": "这是消息正文"
}
2.3 数据库表设计
数据库名称设置为java_chatroom
drop database if exists java_chatroom;
create database java_chatroom character set utf8mb4;
use java_chatroom;
2.3.1 用户表
create table user (userId int primary key auto_increment,
name varchar(50) unique,
password varchar(50),
nickName varchar(50), -- 昵称
iconPath varchar(2048), -- 头像路径
signature varchar(100),-- 个性签名
lastLogout DateTime -- 上次登录时间
);
insert into user values(null, 'test', '123', '阿星', '', '我擅长java', now());
insert into user values(null, 'test2', '123', '阿甜', '', '我擅长唱歌', now());
insert into user values(null, 'test3', '123', '阿琦', '', '我擅长前端', now());
insert into user values(null, 'test4', '123', '阿库', '', '我擅长篮球', now());
2.3.2 频道表
create table channel (channelId int primary key auto_increment,
channelName varchar(50)
);
insert into channel values(null, '体坛赛事');
insert into channel values(null, '娱乐八卦');
insert into channel values(null, '时事新闻');
insert into channel values(null, '午夜情感');
2.3.3 消息表
create table message (messageId int primary key auto_increment,
userId int, -- 谁发的
channelId int, -- 发到哪个频道中
content text, -- 消息内容是啥
sendTime DateTime default now() -- 发送时间
);
insert into message values (null, 1, 1, 'hehe1', now());
insert into message values (null, 1, 1, 'hehe2', now());
insert into message values (null, 1, 1, 'hehe3', now());
以上是关于Web在线聊天室 --- 详细设计的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室 之 用 Redis 实现用户在线离线状态消息处理