websocket实现一对一,群发聊天
websocket介绍
背景
因为公司在做供应链,有供应商发布商品,采购商购买商品,在购买商品的过程中涉及到沟通,因此消息聊天功能就应运而生了。所以就自己手动先写个demo测试下
功能介绍
- 在线消息(双方都在线,正常发送消息)
- 离线消息(一方不在线,发送消息储存起来,下次上线将存储的消息展示给对方看)
- 群发消息(发送者将消息发送到所有在线的接收者)
项目搭建
- 创建springboot项目,引入springboot版本即相关依赖,依赖介绍
jdk 1.8
springboot 2.3.1.RELEASE
lombok 1.18.20
mybatis-plus 3.5.5
fastjson 1.2.74
druid 1.1.23 数据库连接池
mysql-connector-java
- 数据库表设计
因为一对一聊天,涉及到一方发送消息,另一方下线数据接收不到,需要存储起来以便下次对方上线能看到消息。
CREATE TABLE `message` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
`sender_id` bigint NOT NULL COMMENT '发送者id',
`receiver_id` bigint NOT NULL COMMENT '接收者id',
`content` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci COMMENT '发送内容',
`receive_flag` tinyint DEFAULT '0' COMMENT '接收标识,0失败,1成功',
`is_del` tinyint DEFAULT '0' COMMENT '删除标识,0-未删除,1-已删除',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`send_success_flag` tinyint DEFAULT '0' COMMENT '是否发送成功,0失败,1成功',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb3 COMMENT='消息记录';
- 枚举值
因为消息分为点对点,和群发两种类型,所以这里使用了枚举来表示
/**
* @Author: LiFly
* @Date: 2025/2/15 10:50
* @Description: 消息类型枚举
* @Version: 1.0
*/
@Getter
public enum TypeEnum {
/**
* 点对点
*/
SINGLE(1, "点对点"),
/**
* 群发
*/
MASS(2, "群发"),
;
private final Integer key;
private final String value;
TypeEnum(Integer key, String value) {
this.key = key;
this.value = value;
}
/**
* 根据类型获取枚举名称
* @param type 类型
* @return 名称
*/
public static String getNameByType(Integer type) {
for (TypeEnum formType : TypeEnum.values()) {
if (formType.key.equals(type)) {
return formType.value;
}
}
return null;
}
}
- 数据存储,实体类编写mapper
因为涉及到离线消息需要存储,所以使用了myabtis-plus
/**
* 消息记录
* @TableName message
*/
@TableName(value ="message")
public class Message implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 发送者id
*/
private Long senderId;
/**
* 接收者id
*/
private Long receiverId;
/**
*
*/
private String content;
/**
* 接收标识,0失败,1成功
*/
private Integer receiveFlag;
/**
* 删除标识,0-未删除,1-已删除
*/
private Integer isDel;
/**
*
*/
private Date createTime;
/**
*
*/
private Date updateTime;
/**
* 是否发送成功,0失败,1成功
*/
private Integer sendSuccessFlag;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
@Mapper
public interface MessageMapper extends BaseMapper<Message> {
}
这里直接继承了BaseMapper,里面封装了基本的增删改查方法,我没不用再写相关的sql了,到时候直接用就好了。
- 请求参数
@Data
public class MessageReq implements Serializable {
/**
* 消息内容
*/
private String message;
/**
* 发送者id
*/
private Long fromUser;
/**
* 接收者id
*/
private Long toUser;
/**
* 消息类型 1-点对点 2-群发
*/
private Integer type;
}
因为我们是测试demo,请求对象就写的简单了点,项目应