上海网站建设网页制作怎么样,西安千秋网络科技有限公司,如何做企业网站后台管理,一点一创平面设计提示#xff1a;写完文章后#xff0c;目录可以自动生成#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、数据库设计二、实现代码1.SessionWrap2.websocket3.insertMessage4.清除未读 前言
使用WebSocket实现一对一的聊天功能与未读消息功能 一、数据库设计 会话…提示写完文章后目录可以自动生成如何生成可参考右边的帮助文档 文章目录 前言一、数据库设计二、实现代码1.SessionWrap2.websocket3.insertMessage4.清除未读 前言
使用WebSocket实现一对一的聊天功能与未读消息功能 一、数据库设计 会话表 字段名字段类型长度注释conversation_idint11会话IDcreate_timedatetime创建时间conversation_typeint1会话类型 消息表 字段名字段类型长度注释message_idint11消息IDconversation_idint11会话IDsender_idint11发送者IDreceiver_idin t11接收者IDcontenttext消息内容typeint2消息类型informationvarchar255信息sender_imgint11发送者头像IDreceiver_imgint11接收者头像IDmessage_statusint1消息状态1已读0未读create_timedatetime创建时间
二、实现代码
1.SessionWrap
Data
public class SessionWrap {private String from; // 连接人idprivate String type; // 连接类型private Session session;private Date lastTime;
}2.websocket
Component
ServerEndpoint(value /api/websocket/{from}/{type})
public class WebSocketServer {Autowiredprivate RqriMessageService rqriMessageService;public static WebSocketServer webSocketServer;// 所有的连接会话private static CopyOnWriteArraySetSessionWrap sessionList new CopyOnWriteArraySet();private String from;private String type;PostConstructpublic void init() {webSocketServer this;webSocketServer.rqriMessageService this.rqriMessageService;}OnOpenpublic void onOpen(Session session, PathParam(value from) String from, PathParam(value type) String type) {this.from from;this.type type;try {// 遍历list如果有会话更新如果没有创建一个新的for (SessionWrap item : sessionList) {if (item.getFrom().equals(from) item.getType().equals(type)) {item.setSession(session);item.setLastTime(new Date());log.info(【websocket消息】更新连接总数为: sessionList.size());return;}}SessionWrap sessionWrap new SessionWrap();sessionWrap.setFrom(from);sessionWrap.setType(type);sessionWrap.setSession(session);sessionWrap.setLastTime(new Date());sessionList.add(sessionWrap);log.info(【websocket消息】有新的连接总数为: sessionList.size());} catch (Exception e) {log.info(【websocket消息】连接失败错误信息 e.getMessage());}}OnClosepublic void onClose() {try {sessionList.removeIf(item - item.getFrom().equals(from) item.getType().equals(type));log.info(【websocket消息】连接断开总数为: sessionList.size());} catch (Exception e) {log.info(【websocket消息】连接断开失败错误信息 e.getMessage());}}OnMessagepublic void onMessage(String message, Session session) {try {if (ping.equals(message)) {session.getBasicRemote().sendText(ping); // 心跳检测} else {// 将消息插入到数据库JSONObject r webSocketServer.rqriMessageService.insertMessage(message);// 成功if (r.getInteger(code) 200) {JSONObject data r.getJSONObject(data);String senderId data.getString(senderId); // 发送者String receiverId data.getString(receiverId); // 接收者for (SessionWrap item : sessionList) {if (senderId.equals(item.getFrom()) || receiverId.equals(item.getFrom()) ) {item.getSession().getBasicRemote().sendText(r.toJSONString());} }log.info(【websocket消息】发送消息: r.toJSONString());}}} catch (Exception e) {log.info(【websocket消息】发送消息失败错误信息 e.getMessage());}}OnErrorpublic void onError(Session session, Throwable error) {log.error(用户错误,原因:error.getMessage());error.printStackTrace();}}
3.insertMessage
private final String rqriMessageStr rqri_message_unread_;public JSONObject insertMessage(String message) {JSONObject jsonObject new JSONObject();RqriMessage rqriMessage JSONObject.parseObject(message, RqriMessage.class);// 把消息添加到数据库int i rqriMessageMapper.insertSelective(rqriMessage);// 将未读信息添加到redis 添加接收者的未读String conversationId String.valueOf(rqriMessage.getConversationId());String receiverId String.valueOf(rqriMessage.getReceiverId());String key rqriMessageStr conversationId _ receiverId;if (redisUtils.get(key) null) {redisUtils.set(key, 1, 0); // 设置永不过期} else {redisUtils.incr(key, 1); // 未读数量添加1}jsonObject.put(code, 200);jsonObject.put(data, rqriMessage);// 发送者的id和未读数量返回给前端渲染到页面HashMapString, Integer map new HashMap();map.put(num, Integer.valueOf(redisUtils.get(key).toString()));map.put(id, rqriMessage.getSenderId());jsonObject.put(isread, map);return jsonObject;
}4.清除未读
最后在进入聊天页面和退出聊天页面时把未读数量清零。