用户聊天后端(实体类和webSocket引入和配置)
表的设计
用户聊天关系表(chat_user_link)
link_id(主键id)
from_user(发送方用户名,用户表主键)
to_user(接收方用户名,用户表主键)
create_time(创建时间)
聊天列表表(chat_list)
list_id(主键id,自增)
link_id(用户聊天关系表主键)
from_user(发送方用户名)
to_user(接收方用户名)
from_window(发送方是否在窗口)
to_window(接收方是否在窗口)
unread(未读数)
status(列表状态,是否删除)
聊天内容详情表(chat_message)
message_id(主键id,自增)
link_id(用户聊天关系表主键)
from_user(发送方用户名)
to_user(接收方用户名)
content(消息内容)
send_time(发送时间)
type(类型)
is_latest(是否是最后一条消息)
聊天逻辑
1.点击私信按钮
判断是不是第一次聊天,如果是会在主表生成一条记录返回用户聊天关系表id,并在聊天列表表分别插入两条记录,如果不是第一次聊天进入下一步
2.进入聊天对话框
获取近期几条聊天记录,将用户在此对话的窗口(from_window)改为1,即表示在线
3.发送聊天信息
3.1、先判断对方是否在线,不在线的话对方未读数+1
3.2、将上一条最后一条消息状态改为否
3.3、往聊天详情表插入聊天信息数据
选用WebSocket进行客户端与服务端通信
WebSocket 是一种网络传输协议,可在单个 TCP 连接上进行全双工通信,位于 OSI 模型的应用层。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。
避免了轮询或长轮询等的缺点
引入依赖
<!--WebSocket相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
WebSocket配置类
@Configuration
public class WebSocketConfig extends ServerEndpointConfig.Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
//获取httpsession
HttpSession session = (HttpSession) request.getHttpSession();
sec.getUserProperties().put(HttpSession.class.getName(), session);
}
/**
* 注入ServerEndpointExporter,
* 这个bean会自动注册使用了@ServerEndpoint注解声明的WebSocket endpoint
*/
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
WebSocket监听器
监听器类:主要任务是用ServletRequest将我们的HttpSession携带过去
@Component
public class RequestListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre){
//将所有请求都携带上httpSession
((HttpServletRequest) sre.getServletRequest()).getSession();
}
public RequestListener(){}
@Override
public void requestDestroyed(ServletRequestEvent arg0){}
}
实体类
用户聊天关系表
@Entity
@Data
@Table(name = "chat_user_link")
public class chatUserLink implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false,unique = true,length = 20)
private String from_user;
@Column(nullable = false,unique = true,length = 20)
private String to_user;
@Column(nullable = false)
private Date create_time;
}
这里必须要提一句,当时我要建表的时候一直报这个错,浪费了两个小时后才终于在同学的提醒下找到了错误,那就是Date写成了Data,写代码时一定要认真啊!!!
聊天列表
@Entity
@Data
public class chat_list {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Schema(name = "主键")
private long id;
@Column(nullable = false,unique = true,length = 20)
@Schema(name = "用户聊天关系表主键")
private long link_id;
@Column(nullable = false,length = 20)
@Schema(name = "发送方用户名")
private String from_user;
@Column(nullable = false,length = 20)
@Schema(name = "接收方用户名")
private String to_user;
@Column(nullable = false)
@Schema(name = "发送方是否在窗口")
private int from_window;
@Column(nullable = false)
@Schema(name = "接收方是否在窗口")
private int to_window;
@Column(nullable = false)
@Schema(name = "未读消息数")
private int unread;
@Column(nullable = false)
@Schema(name = "列表状态,是否删除")
private int status;
}
聊天内容详情表
@Entity
@Data
public class chatMessage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long message_id;
@Schema(name = "用户聊天关系表主键")
@Column(nullable = false,unique = true)
private long link_id;
@Schema(name = "发送方用户名")
@Column(nullable = false,length = 20)
private String from_user;
@Schema(name = "接收方用户名")
@Column(nullable = false,length = 20)
private String to_user;
@Schema(name = "消息内容")
@Column(nullable = false)
private String content;
@Schema(name = "发送时间")
@Column(nullable = false)
private Date send_time;
@Schema(name = "类型")
@Column(nullable = false)
private String type;
@Schema(name = "是否是最后一条消息")
@Column(nullable = false)
private int is_latest;
}