Selaa lähdekoodia

本地缓存消息优化(冷热数据分离)

xsx 9 kuukautta sitten
vanhempi
commit
aba495227c

+ 1 - 1
im-platform/src/main/java/com/bx/implatform/task/schedule/FileExpireTask.java

@@ -34,7 +34,7 @@ public class FileExpireTask {
     private final MinioProperties minioProps;
 
     @RedisLock(prefixKey = RedisKey.IM_LOCK_FILE_TASK)
-    @Scheduled(cron = "0 * * * * ?")
+    @Scheduled(cron = "0 0 3 * * ?")
     public void run() {
         log.info("【定时任务】过期文件处理...");
         int batchSize = 100;

+ 46 - 19
im-uniapp/store/chatStore.js

@@ -22,7 +22,8 @@ export default defineStore('chatStore', {
 				chat.stored = false;
 				// 清理多余的消息,避免消息过多导致卡顿
 				if (UNI_APP.MAX_MESSAGE_SIZE > 0 && chat.messages.length > UNI_APP.MAX_MESSAGE_SIZE) {
-					chat.messages = chat.messages.slice(0, UNI_APP.MAX_MESSAGE_SIZE);
+					let idx = chat.messages.length - UNI_APP.MAX_MESSAGE_SIZE;
+					chat.messages = chat.messages.slice(idx);
 				}
 				// 暂存至缓冲区
 				cacheChats.push(JSON.parse(JSON.stringify(chat)));
@@ -64,6 +65,7 @@ export default defineStore('chatStore', {
 					lastContent: "",
 					lastSendTime: new Date().getTime(),
 					unreadCount: 0,
+					hotMinIdx: 0,
 					messages: [],
 					atMe: false,
 					atAll: false,
@@ -244,24 +246,28 @@ export default defineStore('chatStore', {
 		deleteMessage(msgInfo, chatInfo) {
 			// 获取对方id或群id
 			let chat = this.findChat(chatInfo);
+			let isColdMessage = false;
 			for (let idx in chat.messages) {
 				// 已经发送成功的,根据id删除
 				if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) {
 					chat.messages.splice(idx, 1);
+					isColdMessage = idx < chat.hotMinIdx;
 					break;
 				}
 				// 正在发送中的消息可能没有id,只有临时id
 				if (chat.messages[idx].tmpId && chat.messages[idx].tmpId == msgInfo.tmpId) {
 					chat.messages.splice(idx, 1);
+					isColdMessage = idx < chat.hotMinIdx;
 					break;
 				}
 			}
 			chat.stored = false;
-			this.saveToStorage();
+			this.saveToStorage(isColdMessage);
 		},
 		recallMessage(msgInfo, chatInfo) {
 			let chat = this.findChat(chatInfo);
 			if (!chat) return;
+			let isColdMessage = false;
 			// 要撤回的消息id
 			let id = msgInfo.content;
 			let name = msgInfo.selfSend ? '你' : chat.type == 'PRIVATE' ? '对方' : msgInfo.sendNickName;
@@ -279,6 +285,7 @@ export default defineStore('chatStore', {
 					if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED) {
 						chat.unreadCount++;
 					}
+					isColdMessage = idx < chat.hotMinIdx;
 				}
 				// 被引用的消息也要撤回
 				if (m.quoteMessage && m.quoteMessage.id == msgInfo.id) {
@@ -288,7 +295,7 @@ export default defineStore('chatStore', {
 				}
 			}
 			chat.stored = false;
-			this.saveToStorage();
+			this.saveToStorage(isColdMessage);
 		},
 		updateChatFromFriend(friend) {
 			let chat = this.findChatByFriend(friend.id)
@@ -336,20 +343,19 @@ export default defineStore('chatStore', {
 			}
 		},
 		refreshChats() {
-			if (!cacheChats) {
-				return;
-			}
+			if (!cacheChats) return;
 			// 排序
-			cacheChats.sort((chat1, chat2) => {
-				return chat2.lastSendTime - chat1.lastSendTime;
-			});
+			cacheChats.sort((chat1, chat2) => chat2.lastSendTime - chat1.lastSendTime);
+			// 记录热数据索引位置
+			cacheChats.forEach(chat => chat.hotMinIdx = chat.messages.length);
 			// 将消息一次性装载回来
 			this.chats = cacheChats;
-			// 清空缓存不再使用
+			// 清空缓存,不再使用
 			cacheChats = null;
-			this.saveToStorage();
+			// 消息持久化
+			this.saveToStorage(true);
 		},
-		saveToStorage(state) {
+		saveToStorage(withColdMessage) {
 			// 加载中不保存,防止卡顿
 			if (this.isLoading()) {
 				return;
@@ -362,12 +368,27 @@ export default defineStore('chatStore', {
 			this.chats.forEach((chat) => {
 				let chatKey = `${key}-${chat.type}-${chat.targetId}`
 				if (!chat.stored) {
+					chat.stored = true;
 					if (chat.delete) {
 						uni.removeStorageSync(chatKey);
 					} else {
-						uni.setStorageSync(chatKey, chat);
+						// 存储冷数据
+						if (withColdMessage) {
+							let coldChat = Object.assign({}, chat);
+							coldChat.messages = chat.messages.slice(0, chat.hotMinIdx);
+							uni.setStorageSync(chatKey, coldChat)
+						}
+						// 存储热消息
+						let hotKey = chatKey + '-hot';
+						if (chat.messages.length > chat.hotMinIdx) {
+							let hotChat = Object.assign({}, chat);
+							hotChat.messages = chat.messages.slice(chat.hotMinIdx)
+							uni.setStorageSync(hotKey, hotChat);
+							console.log("热数据:",hotChat.messages.length)
+						} else {
+							uni.removeStorageSync(hotKey);
+						}
 					}
-					chat.stored = true;
 				}
 				if (!chat.delete) {
 					chatKeys.push(chatKey);
@@ -391,20 +412,26 @@ export default defineStore('chatStore', {
 			this.loadingPrivateMsg = false;
 			this.loadingGroupMsg = false;
 		},
-		loadChat(context) {
+		loadChat() {
 			return new Promise((resolve, reject) => {
 				let userStore = useUserStore();
 				let userId = userStore.userInfo.id;
 				let chatsData = uni.getStorageSync("chats-app-" + userId)
 				if (chatsData) {
 					if (chatsData.chatKeys) {
-						let time = new Date().getTime();
 						chatsData.chats = [];
 						chatsData.chatKeys.forEach(key => {
-							let chat = uni.getStorageSync(key);
-							if (chat) {
-								chatsData.chats.push(chat);
+							let coldChat = uni.getStorageSync(key);
+							let hotChat = uni.getStorageSync(key + '-hot');
+							if (!coldChat && hotChat) {
+								return;
+							}
+							// 冷热消息合并
+							let chat = Object.assign({}, coldChat, hotChat);
+							if (hotChat && coldChat) {
+								chat.messages = coldChat.messages.concat(hotChat.messages)
 							}
+							chatsData.chats.push(chat);
 						})
 					}
 					this.initChats(chatsData);

+ 47 - 13
im-web/src/store/chatStore.js

@@ -69,6 +69,7 @@ export default defineStore('chatStore', {
 					lastContent: "",
 					lastSendTime: new Date().getTime(),
 					unreadCount: 0,
+					hotMinIdx: 0,
 					messages: [],
 					atMe: false,
 					atAll: false,
@@ -246,24 +247,28 @@ export default defineStore('chatStore', {
 		},
 		deleteMessage(msgInfo, chatInfo) {
 			let chat = this.findChat(chatInfo);
+			let isColdMessage = false;
 			for (let idx in chat.messages) {
 				// 已经发送成功的,根据id删除
 				if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) {
 					chat.messages.splice(idx, 1);
+					isColdMessage = idx < chat.hotMinIdx;
 					break;
 				}
 				// 正在发送中的消息可能没有id,只有临时id
 				if (chat.messages[idx].tmpId && chat.messages[idx].tmpId == msgInfo.tmpId) {
 					chat.messages.splice(idx, 1);
+					isColdMessage = idx < chat.hotMinIdx;
 					break;
 				}
 			}
 			chat.stored = false;
-			this.saveToStorage();
+			this.saveToStorage(isColdMessage);
 		},
 		recallMessage(msgInfo, chatInfo) {
 			let chat = this.findChat(chatInfo);
 			if (!chat) return;
+			let isColdMessage = false;
 			// 要撤回的消息id
 			let id = msgInfo.content;
 			let name = msgInfo.selfSend ? '你' : chat.type == 'PRIVATE' ? '对方' : msgInfo.sendNickName;
@@ -281,6 +286,7 @@ export default defineStore('chatStore', {
 					if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED) {
 						chat.unreadCount++;
 					}
+					isColdMessage = idx < chat.hotMinIdx;
 				}
 				// 被引用的消息也要撤回
 				if (m.quoteMessage && m.quoteMessage.id == msgInfo.id) {
@@ -290,7 +296,7 @@ export default defineStore('chatStore', {
 				}
 			}
 			chat.stored = false;
-			this.saveToStorage();
+			this.saveToStorage(isColdMessage);
 		},
 		updateChatFromFriend(friend) {
 			let chat = this.findChatByFriend(friend.id);
@@ -338,20 +344,19 @@ export default defineStore('chatStore', {
 			}
 		},
 		refreshChats() {
-			if (!cacheChats) {
-				return;
-			}
+			if (!cacheChats) return;
 			// 排序
-			cacheChats.sort((chat1, chat2) => {
-				return chat2.lastSendTime - chat1.lastSendTime;
-			});
+			cacheChats.sort((chat1, chat2) => chat2.lastSendTime - chat1.lastSendTime);
+			// 记录热数据索引位置
+			cacheChats.forEach(chat => chat.hotMinIdx = chat.messages.length);
 			// 将消息一次性装载回来
 			this.chats = cacheChats;
 			// 清空缓存
 			cacheChats = null;
-			this.saveToStorage();
+			// 持久化消息
+			this.saveToStorage(true);
 		},
-		saveToStorage() {
+		saveToStorage(withColdMessage) {
 			// 加载中不保存,防止卡顿
 			if (this.isLoading()) {
 				return;
@@ -365,12 +370,26 @@ export default defineStore('chatStore', {
 				// 只存储有改动的会话
 				let chatKey = `${key}-${chat.type}-${chat.targetId}`
 				if (!chat.stored) {
+					chat.stored = true;
 					if (chat.delete) {
 						localForage.removeItem(chatKey);
 					} else {
-						localForage.setItem(chatKey, chat);
+						// 存储冷数据
+						if (withColdMessage) {
+							let coldChat = Object.assign({}, chat);
+							coldChat.messages = chat.messages.slice(0, chat.hotMinIdx);
+							localForage.setItem(chatKey, coldChat)
+						}
+						// 存储热消息
+						let hotKey = chatKey + '-hot';
+						if (chat.messages.length > chat.hotMinIdx) {
+							let hotChat = Object.assign({}, chat);
+							hotChat.messages = chat.messages.slice(chat.hotMinIdx)
+							localForage.setItem(hotKey, hotChat)
+						} else {
+							localForage.removeItem(hotKey);
+						}
 					}
-					chat.stored = true;
 				}
 				if (!chat.delete) {
 					chatKeys.push(chatKey);
@@ -403,9 +422,24 @@ export default defineStore('chatStore', {
 						const promises = [];
 						chatsData.chatKeys.forEach(key => {
 							promises.push(localForage.getItem(key))
+							promises.push(localForage.getItem(key + "-hot"))
 						})
 						Promise.all(promises).then(chats => {
-							chatsData.chats = chats.filter(o => o);
+							chatsData.chats = [];
+							// 偶数下标为冷消息,奇数下标为热消息
+							for (let i = 0; i < chats.length; i += 2) {
+								if (!chats[i] && !chats[i + 1]) {
+									continue;
+								}
+								let coldChat = chats[i];
+								let hotChat = chats[i + 1];
+								// 冷热消息合并
+								let chat = Object.assign({}, coldChat, hotChat);
+								if (hotChat && coldChat) {
+									chat.messages = coldChat.messages.concat(hotChat.messages)
+								}
+								chatsData.chats.push(chat);
+							}
 							this.initChats(chatsData);
 							resolve();
 						})