当前位置: 首页 > news >正文

【分布式websocket 】前端vuex管理客户端消息crud!使用localStorage来存储【第19期】

前言

聊天系统客户端是要存储消息的,因为所有所有的历史消息都从服务器拉的话一方面服务器压力大,另一方面也耗费用户流量。所以客户端存储消息是势在必行的。如何存储呢上一篇文章也写了,大概就是浏览器的话是localStorage或者IndexedDB。然后手机端和桌面端就是sqllite了。这样子消息的存储结构以及消息的增删改查也是需要一套的了。本篇文章将着重从自己的开源项目技术选型来进行分享。vuex进行增删改查。B站会录制视频同步分享。

目前已经写的文章有。并且有对应视频版本。
git项目地址 【IM即时通信系统(企聊聊)】点击可跳转
sprinboot单体项目升级成springcloud项目 【第一期】
前端项目技术选型以及页面展示【第二期】
分布式权限 shiro + jwt + redis【第三期】
给为服务添加运维模块 统一管理【第四期】
微服务数据库模块【第五期】
netty与mq在项目中的使用(第六期(废弃))】
分布式websocket即时通信(IM)系统构建指南【第七期】
分布式websocket即时通信(IM)系统保证消息可靠性【第八期】
分布式websocket IM聊天系统相关问题问答【第九期】
什么?websocket也有权限!这个应该怎么做?【第十期】
分布式ID是什么,以美团Leaf为例改造融入自己项目【第十一期】
IM聊天系统为什么需要做消息幂等?如何使用Redis以及Lua脚本做消息幂等【第12期】
微信发送一条消息经历哪些过程。企业微信以及钉钉的IM架构对比【第13期】
微信群为什么上限是500人,IM设计系统中的群聊的设计难点【第14期】
【分布式websocket】RocketMQ发送消息保证消息最终一致性需要做哪些处理?【第15期】

【分布式websocket】群聊中的各种难点以及解决推拉结合【第16期】

【分布式webscoket】未读消息如何设计?解决缓存与数据库数据一致性!推送未读消息流程【第17期】

IM系统客户端消息存储在手机电脑浏览器分别存储在什么地方?对消息加密策略?如何保证服务端消息和客户端消息一致性【第18期】
【分布式websocket】聊天系统消息加密如何做【第20期】
【分布式webscoket】IM聊天系统消息如何存储 如何分库分表以及Seata解决事务以及ShardingSphere-Scaling解决数据迁移【第21期】

客户端消息结构:

技术选型在浏览器端的localStorage,当然是有缺陷的。后续根据情况再进行优化。页面如下。
在这里插入图片描述

在这里插入图片描述

chats: []            数组 存放每一个聊天用户lastContent:	 存放最后一条消息用于显示tagrgetId: 		 标识唯一会话,可以考虑改成会话id,目前使用的是单聊是对方的id,群聊是群聊idtype :			 标记是私聊还是群聊unreadCount:	 未读消息数量 (TODO)messgaes :[]    存放每一个用户下面具体的聊天消息,数组type:		 用于标记消息是自己发的还是别人的,用于前端显示样式group:        用于区分消息是群聊还是单聊 ,创建消息的时候会使用到msgid:        消息唯一idavatarUrl:    用于页面上面显示聊天头像框content:	     消息内容tagrgetId:     标识唯一会话id
privateMsgMaxId: 拉取消息id

如下
客户端消息操作主要是 .

  • 添加 1.上线后拉取未读消息要存储未读消息 2.发送消息需要添加消息3.收到消息需要添加
  • 查询 进入聊天页面需要可以查到消息
  • 修改 消息发送失败需要修改状态发送失败
  • 删除 前端存储有限制只能维护一定时间的历史消息。更多的历史消息查询客户端

vuex基本概念概述

export default createStore({state,mutations,actions,getters,modules: {}
})

大概就是这么几个部分。
总结来说,Getter 用于获取由 state 计算得出的数据;
Mutation 用于同步地改变 state,
Action 则封装了异步操作,并最终通过 commit 来间接触发 mutations 更新状态。
state 就是封装变量的地方。

Vuex 允许将应用程序的状态集中存储在一个共享的 store 中,避免了组件之间通过 props 和 events 进行状态传递的复杂性和繁琐性。这使得状态管理更加清晰和易于维护。通过 Vuex 管理状态,整个应用程序共享同一个状态树,确保了状态的一致性和同步性。

场景介绍

消息查询
// 创建一个计算属性,该属性基于其他响应式状态计算值const computedChats = computed(() => {let chat = null;console.log("computedChats route.query.groupId", route.query.groupId);if (state.current == 1) {chat = {targetId: state.toUser.openid,};} else {chat = {// targetId: state.toUser.openid,targetId: state.groupId,};}const idx = store.getters.findChatIdx(chat);if (idx == null || idx == undefined) {return [];}if (store.state.chats[idx] == null ||store.state.chats[idx] == undefined) {return [];}console.log("computedChats idx", idx);console.log("computedChats 寻找成功啦", store.state.chats[idx]);return store.state.chats[idx];});

封装了一个计算属性。用于监听state里面的消息变化。逻辑大概是拿到当前会话的id,单聊的话就是对话的openid。然后去store里面去找一下。找不到的返回空数组。找到的话返回当前聊天下的所有信息.

对应前台页面

渲染一下这个compute属性

   <list-scroll :scroll-data="computedChats.messages"><div class="swiper-container"><divclass="content"v-for="(item, index) in computedChats.messages":key="index"><div class="d-felx justify-start " v-if="item.type === 'self'"><div style="display: flex;"><van-imagewidth="35px"height="35px"fit="cover":src="userInfo.avatarUrl"/><div class="font-18 content1"><text>{{ item.content }}</text></div></div></div><divstyle="display: flex; justify-content: flex-end;"v-if="item.type === 'receive'"><div class="font-18 content2"><text>{{ item.content }}</text></div><div class=""><van-imagewidth="35px"height="35px"fit="cover":src="toUser.avatarUrl"/></div></div></div></div></list-scroll>

消息添加

分为离线数据添加 和在线数据添加。
离线数据添加需要使用到action,异步的去后台拉取然后插入。
在线数据直接调用mutation数据插入。

 /*** 插入消息.* @param {*} state* @param {*} msgInfo 当前消息*/insertMessage(state, msgInfo) {console.log("insertMessage",msgInfo)state.privateMsgMaxId = msgInfo.msgId;state.groupMsgMaxId = msgInfo.msgId;// 如果是已存在消息,则覆盖旧的消息数据let chat = this.getters.findChat(msgInfo);if (chat == null) {this.commit("createChat", msgInfo);chat = this.getters.findChat(msgInfo);}if(chat == null){console.log("没有找到chat",chat);return;}chat.messages.push(msgInfo);this.commit("saveToStorage");},

第一步,先更新一下这个最大的消息id。然后去store里面去找当前消息。找到之后给当前chat里面推送消息。并且同步的保存到Storgae里面.

/***  state.chats 将更新后的存储.* @param {*} state*/saveToStorage(state) {let userId = state.userInfo.openid;let key = "chats-" + userId;let chatsData = {privateMsgMaxId: state.privateMsgMaxId,groupMsgMaxId: state.groupMsgMaxId,chats: state.chats,};localStorage.setItem(key, JSON.stringify(chatsData));},

这个存储的逻辑就是简单的将消息序列化后放到localStorage里面。

强调一下这个离线消息拉取的步骤;需要后台sql的配合。
 async pullOffline(ctx) {// 获取当前store中的privateMsgMaxIdconst privateMsgMaxId = ctx.state.privateMsgMaxId+"";console.log("privateMsgMaxId",ctx.state.privateMsgMaxId)const res = await getChatContentAll(privateMsgMaxId);const contentAll = res.contentfor (var i = 0; i < contentAll.length; i++) { ctx.commit("initInsertMessage", contentAll[i]); }}

调用后台接口getChatContentAll 然后获取未拉取的离线消息然后进行存储。

相关文章:

【分布式websocket 】前端vuex管理客户端消息crud!使用localStorage来存储【第19期】

前言 聊天系统客户端是要存储消息的&#xff0c;因为所有所有的历史消息都从服务器拉的话一方面服务器压力大&#xff0c;另一方面也耗费用户流量。所以客户端存储消息是势在必行的。如何存储呢上一篇文章也写了&#xff0c;大概就是浏览器的话是localStorage或者IndexedDB。然…...

venv uvicorn python 虚拟服务器外网无法访问

python -m venv .venv source ./.venv/bin/activate pip install -r requirements.txt ./run.sh source ./.venv/bin/activate uvicorn main:app --reload 虚拟web服务器外网访问控制台启动命令用以下代码启动 uvicorn main:app --host 0.0.0.0 --port 8501 --reload 启动到后…...

一款博客网站源码

一款博客网站源码 源码软件库 为大家内置了主题 清爽又强大真正的永久可用的一条源码&#xff0c;该版本为整合版本&#xff0c;内置了Joe主题&#xff0c;搭建后直接启用即可~ 安装环境要求&#xff1a; PHP 7.2 以上 MySQL, PostgreSQL, SQLite 任意一种数据库支持&#xff…...

Mr-Robot1靶场练习靶场推荐小白入门练习靶场渗透靶场bp爆破wordpress

下载链接&#xff1a; Mr-Robot: 1 ~ VulnHub 安装&#xff1a; 打开vxbox&#xff0c;菜单栏----管理----导入虚拟电脑 选择下载完的ova文件&#xff0c;并修改想要保存的位置&#xff08;也可以保持默认位置&#xff09; 导入完成后可以根据自己的情况去配置网络链接方式 完成…...

数据仓库的设计开发应用(三)

目录 五、数据仓库的实施&#xff08;一&#xff09;数据仓库的创建&#xff08;二&#xff09;数据抽取转换加载 六、数据仓库系统的开发&#xff08;一&#xff09;开发任务&#xff08;二&#xff09;开发方法&#xff08;三&#xff09;系统测试 七、数据仓库系统的应用&am…...

【04】WebAPI

WebAPI 和标准库不同,WebAPI 是浏览器提供的一套 API,用于操作浏览器窗口和界面 WebAPI 中包含两个部分: BOM:Browser Object Model,浏览器模型,提供和浏览器相关的操作DOM:Document Object Model,文档模型,提供和页面相关的操作BOM BOM 提供了一系列的对象和函数,…...

数据预处理在数据挖掘中的重要性

数据挖掘作为从大量数据中提取有用信息和知识的过程&#xff0c;其结果的准确性和可靠性直接受到数据质量的影响。因此&#xff0c;数据预处理在数据挖掘中扮演着至关重要的角色。让我们探讨数据质量对数据挖掘结果的影响&#xff0c;并介绍常见的数据预处理方法以及它们如何提…...

Java并发编程—JUC线程池架构

Java并发编程&#xff08;JUC&#xff0c;Java Utilities Concurrency&#xff09;中的线程池架构是Java提供的一种用于管理和复用线程的机制。线程池的主要目标是减少线程创建和销毁的开销&#xff0c;提高系统的响应速度&#xff0c;并通过合理的线程管理和资源分配&#xff…...

Android input输入子系统

一.Android input输入子系统简介 Input系统是Android系统中负责处理用户输入操作的核心组件&#xff0c;它负责从各种输入设备&#xff08;如屏幕、键盘、鼠标等&#xff09;获取原始的输入事件&#xff08;如按键、触摸、滑动等&#xff09;&#xff0c;并将其转换为Android应…...

如何在webapp中于动发布一个应用

目录 第一步&#xff1a;在webapp文件夹内自定义文件夹第二步&#xff1a;生成一个文本&#xff0c;并把后缀改为 .html第三步&#xff1a;进入bin文件夹打开服务第四步&#xff1a;打开方式选择java第六步&#xff1a;输入你想输出的东西第七步&#xff1a;双击运行即可 第一步…...

部署一个本地的ChatGPT(Ollama)

一 下载Ollama Ollama下载地址&#xff1a;https://ollama.com/download 下载完后 二 安装运行 双击下载好的OllamaSetup.exe开发 安装Ollama: 安装完成后&#xff0c;多了一个Ollama的菜单如下图 &#xff1a; Ollama安装好默认是配置开机运行&#xff0c;如果没有运行可以在…...

Vue 3中的reactive:响应式状态的全面管理

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

【网络】详解HTTPS及探究加密过程

目录 一、什么是HTTPS1、加密解密是什么2、为什么要加密3、常见的加密方式1、对称加密2、非对称加密 二、探究HTTPS如何实现加密1、方案一----只使用对称加密2、方案二----只使用非对称加密3、方案三----双方都使用非对称加密4、方案四----非对称加密 对称加密5、中间人攻击6、…...

【C语言】字符与字符串---从入门到入土级详解

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C语言 ⚙️操作环境:Visual Studio 2022 目录 一.字符类型和字符数组&#xff08;串&#xff09;简介 1.ASCII 2.定义&#xff0c;初始化&#xff0c;使用 1>字符的定义及初始化 2>字符串的定义及初始化 二.…...

Github Copilot 工具,无需账号,一键激活

① 无需账号&#xff0c;100%认证成功&#xff01;0风险&#xff0c;可联网可更新&#xff0c;&#xff0c;支持copilot版本升级&#xff0c;支持chat ② 支持windows、mac、linux系统等设备 ③一号通用&#xff0c;支持所有IDE(AppCode,CLion,DataGrip,GoLand,IntelliJ IDEA …...

node: -max-old-space-size=xxx is not allowed in NODE_OPTIONS

问题描述 在启动node项目时&#xff0c;出现了OOM参照网上的处理方案&#xff0c;设置了环境变量&#xff1a; export NODE_OPTIONS"–max-old-space-size8192"当再次通过npm run docs:dev运行node项目的时候出现了如下错误&#xff1a; node: -max-old-space-siz…...

k8s编排系统

Kubernetes&#xff08;简称K8s&#xff09;是一个开源的容器编排系统&#xff0c;由Google基于其内部的Borg项目开发&#xff0c;并于2014年正式对外发布。目前&#xff0c;Kubernetes已成为云原生计算基金会&#xff08;Cloud Native Computing Foundation, CNCF&#xff09;…...

samba服务器的配置

需求&#xff1a;在Linux上搭建一个文件共享服务&#xff0c;创建不同的账号给予不同的权限&#xff0c;在windows可以直接访问该共享目录 介绍 Samba 是一个强大的工具&#xff0c;使得不同操作系统之间可以无缝地共享文件和资源&#xff0c;促进了跨平台环境下的协作和通信…...

H12-821_279

279.第三类LSA的Link ID是: A.所描述的ABR的Router ID B.所在网段上DR的端口IP地址 C.所描述的目的网段 D.生成这条LSA的路由器的Router ID 答案&#xff1a;C 注释&#xff1a; OSPF的LSA可以单独描述网络信息、拓扑信息&#xff0c;也可以同时描述网络信息和拓扑信息。 LSA3…...

Stable Diffusion科普文章【附升级gpt4.0秘笈】

随着人工智能技术的飞速发展&#xff0c;我们越来越多地看到计算机生成的艺术作品出现在我们的生活中。其中&#xff0c;Stable Diffusion作为一种创新的图像生成技术&#xff0c;正在引领一场艺术创作的革命。本文将为您科普Stable Diffusion的相关知识&#xff0c;带您走进这…...

Lua 如何在Lua中调用C/C++函数

Lua调用C函数有两种方式 程序主体在C中运行&#xff0c;C函数注册到Lua中。C调用Lua&#xff0c;Lua调用C注册的函数&#xff0c;C或者Lua得到函数的执行结果。程序主体在Lua中运行&#xff0c;C函数作为库函数供Lua使用。 C的代码如下 如何在Lua脚本中调用这个C语言函数(ad…...

JVM学习-类加载

目录 1.类文件结构 2.类加载器 3.类加载的三个阶段 3.1加载 3.2链接 3.2.1验证 3.2.2准备阶段 3.2.3解析阶段 3.3初始化 4.拓展&#xff1a;反射 4.1获取类对象 4.2创建实例 4.3获取方法 4.4方法调用 1.类文件结构 2.类加载器 类加载器用来将类文件的二进制字节码加载到JV…...

PyCharm中如何使用不同的虚拟环境

1. 简介 有些项目用老的运行环境&#xff0c;而有些项目用新的运行环境&#xff0c;那么我们在运行这些代码&#xff08;比如跑对比实验的时候&#xff09;如何进行切换呢&#xff0c;这时候就可以使用虚拟环境啦 2. 虚拟环境的创建 首先启动Anaconda Prompt 并在其中执行如…...

Unity Live Capture 中实现面部捕捉同步模型动画

Unity Face Capture 是一个强大的工具&#xff0c;可以帮助你快速轻松地将真实人脸表情捕捉到数字模型中。在本文中&#xff0c;我们将介绍如何在 Unity Face Capture 中实现面部捕捉同步模型动画。 安装 |实时捕获 |4.0.0 (unity3d.com) 安装软件插件 安装 Live Capture 软件…...

Codeforces Round 932(div2)||ABD

A-Entertainment in MAC 题意 可以对一个字符串进行两种操作&#xff1a; 将字符串反转将该字符串反转后接在原串的后面。 可以进行任意次上述操作&#xff0c;获得字典序最小的字符串。 数据范围 t ( 1 ≤ t ≤ 500 ) t(1≤t≤500) t(1≤t≤500) n ( 2 ≤ n ≤ 1 0 9 ) n…...

基于最小二乘法的太阳黑子活动模型参数辨识和预测matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于最小二乘法的太阳黑子活动模型参数辨识和预测matlab仿真。太阳黑子是人们最早发现也是人们最熟悉的一种太阳表面活动。因为太阳内部磁场发生变化&#xff0c;…...

VSCode配置cuda C++编程代码提示的详细步骤

目录 VSCode配置cuda C++编程代码提示的详细步骤: 1、cuda编译环境的安装:...

JUnit 面试题及答案整理,最新面试题

JUnit中的断言&#xff08;Assert&#xff09;有哪些类型&#xff1f; JUnit提供了多种断言类型来帮助测试代码的正确性。常见的断言类型包括&#xff1a; 1、assertEquals&#xff1a; 用于检查两个值是否相等。如果不相等&#xff0c;测试失败。 2、assertTrue和assertFal…...

使用Lua编写Wireshark解析ProtoBuf插件

文章目录 Wireshark Protobuf Lua-dissectorStep 1: 获取 WiresharkStep 2: 配置ProtoBuf相关设置添加ProtoBuf查找路径 Step 3 运行和调试Lua代码1. 添加Lua脚本2. 运行和调试 Step 4: 写Lua Dissector代码 :)Step 5(Optional): Decode AsGithub工程地址 Wireshark Protobuf L…...

ClickHouse副本节点数据损坏恢复

参考链接&#xff1a;https://blog.csdn.net/qq_42082701/article/details/127771766 参考链接&#xff1a;https://kb.altinity.com/altinity-kb-setup-and-maintenance/suspiciously-many-broken-parts/ # 背景CK配置为1分片2副本# 配置参数,这里我们将max_suspicious_brok…...