【分布式websocket】表情怎么做?自制表情包和Unicode表情符号区别?表情编解码?【20期】

前言

表情包是聊天系统中一个比较常见的功能。常见的表情表分为两种是类型。
一种是Unicode表情,另外一种是图片表情。我们这篇文章两种都会涉及。
图片类表情包会涉及到编解码。不会将发送消息的图片的url地址也一并存入数据库中。
文章将会从表情分类。表情编解码。表情展示等方面来分享。还有就是分享一下表情包后台的数据结构。比如允许用户自己创建表情包之类的功能。

目前已经写的文章有。并且有对应视频版本。关注我的B站查看视频。
git项目地址 【IM即时通信系统(企聊聊)】点击可跳转

分布式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 】前端vuex管理客户端消息crud!使用localStorage来存储【第19期】

vant官网
https://vant-contrib.gitee.io/vant/v3/#/zh-CN/popup

设计过程

是否需要存储数据库

存储URL到数据库的情况:

  1. 表情自定义性高:如果你的IM系统允许用户上传自定义表情,那么每个表情的URL都是唯一的,需要存储到数据库中以便检索和显示。
  2. 动态表情包:如果系统支持动态添加或更新表情包,那么表情的URL可能会变化,存储URL到数据库可以方便管理和更新。
  3. 访问控制:如果某些表情需要根据用户权限显示(如VIP表情),则可能需要将表情的URL和权限信息存储到数据库中,以便进行权限验证。
    不需要存储URL到数据库的情况:
  4. 固定的表情集:如果你的系统使用的是一组固定的、预先定义好的表情,且这些表情不会频繁变更,那么可以将表情的URL硬编码在客户端或服务器的配置文件中,而不是存储在数据库里。
  5. 简化设计:为了简化数据库设计和减少数据库操作,如果表情的管理和使用相对简单,可以考虑不将URL存储在数据库中。
    实现示例
    对于不存储URL到数据库的设计,你可以在客户端或服务器上维护一个表情的映射表,将特定的标记映射到对应的URL。例如,使用一个JSON对象存储表情的标记和URL:

对于固定和简单的表情系统,不存储URL可能是一个更简洁高效的选择。

数据库字符集设置

要在Java应用程序中通过数据库连接支持存储和检索表情符号(如Unicode中的Emoji),确实需要注意数据库的字符集配置,特别是对于MySQL数据库。以下是一些关键的注意事项:

  1. 使用MySQL 5.5.3及以上版本
    从MySQL 5.5.3版本开始,引入了utf8mb4字符集,它支持存储4字节的Unicode字符。这对于存储表情符号是必需的,因为许多表情符号(包括所有新的表情符号)需要4字节的Unicode编码。如果使用utf8字符集(最多只支持3字节的Unicode字符),则无法存储这些表情符号。
  2. 使用utf8mb4字符集
    为了在MySQL数据库中支持表情符号,你需要确保数据库、表和连接使用utf8mb4字符集。这包括:
    数据库字符集:创建数据库时指定utf8mb4字符集。
  CREATE DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

表字符集:创建表时指定utf8mb4字符集。

  CREATE TABLE mytable (id INT PRIMARY KEY,text VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci);

连接字符集:确保Java应用程序与MySQL数据库的连接使用utf8mb4字符集。如果使用JDBC连接MySQL,可以在连接URL中指定字符集参数

  String url = "jdbc:mysql://localhost:3306/mydatabase?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";

支持表情符号存储的关键是使用utf8mb4字符集。确保数据库、表和连接都正确配置了这个字符集。此外,考虑使用MySQL的较新版本以获得更好的性能和特性支持。在Java应用程序中,通过JDBC连接时,确保连接字符串正确配置了字符编码参数。

流程
  1. 表情包资源准备
    收集或设计表情图片:首先需要一组表情图片,可以是通用的表情符号,也可以是特定主题的自定义设计。
    优化图片:为了提高加载速度和减少数据传输量,应对图片进行压缩和优化。
    存储:将表情图片存储在服务器上,可以使用CDN(内容分发网络)来加速全球的访问速度。
  2. 数据库设计
    设计数据库来管理表情包和表情图片。一个基本的设计可能包括两个表:一个用于存储表情包信息,另一个用于存储表情图片信息。
  3. 前端实现
    表情选择界面:在IM客户端中实现一个表情选择界面,用户可以浏览和选择表情包中的表情。
    表情显示:在消息输入框和聊天记录中,支持显示选中的表情图片。
    快捷输入:(可选)支持通过特定的快捷方式(如输入😄)来快速插入表情。
  4. 消息处理
    表情编码:当用户发送包含表情的消息时,需要将表情转换为一种编码形式(如特定的标记或URL),以便在接收端正确解析和显示。
    表情解码:在消息接收端,解析消息内容中的表情编码,将其转换回对应的表情图片进行显示。
  5. 示例代码
    假设用户选择了一个表情,前端将表情编码为特定的标记或URL,发送到服务器。在接收端,解析这些标记并显示对应的表情图片。
    发送端:
// 假设用户选择了一个笑脸表情
const message = "你好啊 😄";
// 将表情转换为编码或URL(这里仅为示例,实际实现可能会复杂)
const encodedMessage = "你好啊 [emoji:smile]";
// 接收到的消息
const receivedMessage = "你好啊 [emoji:smile]";
// 解析消息中的表情编码,将其替换为<img>标签显示表情图片
const displayedMessage = receivedMessage.replace(/\[emoji:(\w+)\]/g, '<img src="path/to/$1.png">');
  1. 注意事项
    性能优化:考虑使用雪碧图(CSS Sprite)或WebP格式来减少HTTP请求和优化图片加载。
    兼容性:确保表情图片在不同设备和平台上都能正确显示。
    用户体验:提供易于使用的表情选择界面,支持搜索和分类浏览表情包。

聊天框前端样式

  <!-- 底部表情包 --><div class="nav-bar-chat "><ul class="nav-list"><div class="nav-list-item"><span @click="toggleEmojiPanel">😉</span></div><div class="nav-list-item"><span @click="toggleEmojiPanel">拍摄</span></div><div class="nav-list-item"><span @click="toggleEmojiPanel">图片</span></div><div class="nav-list-item"><span @click="toggleEmojiPanel">文件</span></div><div class="nav-list-item"><span @click="toggleEmojiPanel">语音</span></div><div class="nav-list-item"><span @click="toggleEmojiPanel">视频</span></div></ul><div v-if="showEmojiPanel" class="emoji-panel"><van-grid column-num="5"><van-grid-itemv-for="(emoji, index) in emojis":key="index"@click="addEmoji(emoji)"><van-imagev-if="emoji.src"width="35px"height="35px"fit="cover":src="emoji.src"/><div v-if="!emoji.src">{{ emoji.name }}</div><!-- <img :src="emoji.src" :alt="emoji.name" class="emoji-img" /> --></van-grid-item></van-grid></div></div>

更新脚本逻辑
添加或修改方法来控制表情面板的显示和隐藏。

 //切换表情面板const toggleEmojiPanel = function() {state.showEmojiPanel = !state.showEmojiPanel; // 切换表情面板的显示状态};//添加表情const addEmoji = function(emoji) {if (emoji.type == "pic") {state.content += emoji.encode;} else {state.content += emoji.name;}// 简化处理,实际应用中可能需要特殊处理state.showEmojiPanel = false; // 选择表情后关闭面板};

通过这种方式,表情面板将作为聊天输入框的直接扩展。用户可以通过点击表情按钮来显示或隐藏表情面板,并从中选择表情添加到输入框中。

表情包json
 //表情包showEmojiPanel: false, // 控制表情包面板的显示emojis: [{ id: "1", type: "base", name: "📩" },{ id: "2", type: "base", name: "🎉" },{ id: "3", type: "base", name: "👉" },{ id: "4", type: "base", name: "😉" },{ id: "5", type: "base", name: "💙" },{ id: "6", type: "base", name: "🍉" },{ id: "7", type: "base", name: "🌙" },{ id: "8", type: "base", name: "🕙" },{ id: "9", type: "base", name: "🍅" },{ id: "10", type: "base", name: "🐑" },{ id: "11", type: "base", name: "🔱" },{ id: "12", type: "base", name: "🎱" },{ id: "131", type: "base", name: "⚡" },{ id: "14", type: "base", name: "💺" },{ id: "15", type: "base", name: " 👇 " },{id: "16",type: "pic",name: " 头像 ",src:"https://edu-renyun.oss-cn-beijing.aliyuncs.com/2021/07/26/a10016be5a4348a885bc79bb7bf78ad4logo1.png",encode: "[emoji:avatar]",},{id: "17",type: "pic",name: " 头像 2",src:"https://edu-renyun.oss-cn-beijing.aliyuncs.com/2021/07/26/0ea48cb529e54573ae791ffbde3fcd9fu=2095913610,1514262792&fm=26&gp=0.jpg",encode: "[emoji:avatar2]",},// 更多表情...],
前端显示表情包方案

通过v-html来解析包含标签的消息内容。解码的时候转换成url地址。

 					 <divref="contentArea"v-html="decodeCodeToEmoji(item.content)"></div>
封装函数

为了实现点击图片将其转换为特定编码(例如[emj])并在聊天消息框中显示,然后在显示时将编码解码为标签的功能,你可以创建两个函数:encodeEmojiToCode和decodeCodeToEmoji。以下是如何封装这两个函数的示例:

 // 将特定编码转换为<img>标签用于显示const decodeCodeToEmoji = function(message) {const avatarRegex = /\[emoji:avatar(\d+)?\]/g;let match;const avatars = state.emojis;while ((match = avatarRegex.exec(message)) !== null) {// const avatarIndex = match[1]; // 获取头像编号 // 获取头像自定义标识符("avatar" 或 "avatar2")const avatar = avatars.find((a) => a.encode === match[0]); // 查找对应的头像信息if (avatar) {message = message.replace(match[0],`<img src="${avatar.src}"   style="width: 25px; height: 25px; border-radius: 50%;" alt="${avatar.name}" />`);}}return message;};
使用编码和解码函数

当用户点击一个表情图片时,你可以调用encodeEmojiToCode函数将图片转换为编码,并将这个编码添加到聊天输入框的内容中。在发送消息或将消息显示到聊天界面时,使用decodeCodeToEmoji函数将编码转换回标签。

//添加表情const addEmoji = function(emoji) {if (emoji.type == "pic") {state.content += emoji.encode;} else {state.content += emoji.name;}// 简化处理,实际应用中可能需要特殊处理state.showEmojiPanel = false; // 选择表情后关闭面板};
				 <divref="contentArea"v-html="decodeCodeToEmoji(item.content)"></div>

自定义表情包结构设计

CREATE TABLE yan_im_emoji_packs (pack_id INT AUTO_INCREMENT PRIMARY KEY,pack_name VARCHAR(255) NOT NULL,description TEXT,create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE yan_im_emojis (emoji_id INT AUTO_INCREMENT PRIMARY KEY,pack_id INT,emoji_url VARCHAR(255) NOT NULL,shortcut VARCHAR(50),  -- 可选,用于快速输入的快捷方式FOREIGN KEY (pack_id) REFERENCES emoji_packs(pack_id) ON DELETE CASCADE
);

这块留一个小尾巴

聊天发送消息的框其实是一个简易的富文本编辑器。因为聊天消息框支持换行,支持显示表情,支持复制粘贴等功能就是一个简易的富文本编辑器。引用其他的组件样式方面和实用性方面不太好。所以计划自己写。待做

创建富文本编辑器
  1. 创建富文本编辑器组件
    首先,创建一个新的 Vue 组件 RichTextEditor.vue:
<template><div class="rich-text-editor"><div class="toolbar"><!-- 表情按钮 --><van-button icon="smile-o" @click="insertEmoji">表情</van-button></div><divref="editor"class="editor"contenteditable="true"@input="updateContent"@blur="updateContent"></div></div>
</template><script>
export default {data() {return {content: '',};},methods: {insertEmoji() {// 示例:插入一个静态表情图片const imgHtml = '<img src="path/to/your/emoji.png" alt="emoji" class="emoji">';this.$refs.editor.innerHTML += imgHtml;this.updateContent();},updateContent() {this.content = this.$refs.editor.innerHTML;// 在这里,你可以发出事件,将内容同步到父组件或进行保存this.$emit('update:content', this.content);},},
};
</script><style scoped>
.rich-text-editor .editor {border: 1px solid #ccc;min-height: 100px;padding: 10px;margin-top: 10px;
}.emoji {width: 24px;height: 24px;
}
</style>
  1. 使用富文本编辑器组件
    在你的页面或父组件中引入并使用这个富文本编辑器组件:
<template><div><rich-text-editor @update:content="handleContentUpdate"></rich-text-editor></div>
</template><script>
import RichTextEditor from './RichTextEditor.vue';export default {components: {RichTextEditor,},methods: {handleContentUpdate(content) {console.log('Updated content:', content);// 处理更新的内容,例如保存到数据或发送到服务器},},
};
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/769738.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

添加网址到主页

基于localStorage的网址收藏夹-CSDN博客 为了通过安卓菜单添加网址到主页中&#xff0c;调试了几个小时&#xff0c;主要踩了几个坑。 1.localStorage 通过域名隔离&#xff0c;需要加载主页才能读写。 2.WebView 可以不显示&#xff0c;但是 JS 代码要放在 window.onload 中…

oracle19c单机版补丁19.3.0.0升级到19.22.0.0

oracle19c单机版补丁升级到19.22.0.0 一、获取补丁包 查看之前的版本 column product format A30 column version format A15 column version_full format A20 column status format A15 select * from product_component_version;二、备份opatch和数据库文件 su - oracle …

封装-练习

T2、以面向对象的思想&#xff0c;编写自定义类描述IT从业者。设定属性包括&#xff1a;姓名&#xff0c;年龄&#xff0c;技术方向&#xff0c;工作年限&#xff1b;方法包括&#xff1a;工作。 要求&#xff1a; 设置属性的私有访问权限&#xff0c;通过公有的get,set方法实现…

AD域的使用

一&#xff0c;部署共享网络驱动器 1/根目录下创建共享资料库-共享 2/用户-首选项-windows设置-网络驱动器-新建-映射驱动器 3/创建-共享路径-驱动器号(可固定/可随机) 4/更新策略:gpupdate /force 5/客户端查看 首先我们打开服务器此电脑 建立一个文件夹 右击文件夹点击属…

node整理学习(二)

模块化的概念 一、什么是模块化 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层把系统划分成若干模块的过程&#xff0c;模块是可组合、分解和更换的单元 二、模块化的好处 1、提高了代码的复用性 2、提高了代码的可维护性 3、可以实现按需加载 三、模块化规范 …

Avalonia(11.0.2)+.NET6 打包设置发布包的版本号

Avalonia11.0.2+.NET6 打包设置发布包的版本号 系统版本如何打包设置打包的版本号本文是对上一篇打包文章的补充,后台好多人私信我说打包的版本号如何设置,今天出个补充说明 Avalonia(11.0.2)+.NET6 打包运行到银河麒麟V10桌面系统 系统版本 如何打包 Avalonia(11.0.2)+.NET…

MVC与MVVM:两种前端架构模式对比

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

pytest教程-19-pytest.ini配置文件

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest内置fixture的使用方法&#xff0c;本小节我们讲解一下pytest.ini文件的配置方法。 pytest配置文件可以改变pytest的运行方式&#xff0c;它是一个固定的文件pytest.ini文件&#xff0c…

OpenGL学习笔记【4】——创建窗口,给窗口添加渲染颜色

一、前三章节的前情回顾 章节一&#xff1a;上下文(Context) OpenGL学习笔记【1】——简介-CSDN博客 章节一讲述了OpenGL在渲染的时候需要一个Context来记录了OpenGL渲染需要的所有信息和状态&#xff0c;可以把上下文理解成一个大的结构体&#xff0c;它里面记录了当前绘制使…

C#.NET 与 Python 交互

若你要用.NET和Python交互&#xff0c;那么你可以使用两种技术&#xff1a;IronPython 和 Python.NET 。 但两者的基础实现和目标场景都不同&#xff0c;因此如何使用它们也有所不同。 IrconPython简称 IPy , Python.NET 也叫 pythonnet 或 Python for .NET &#xff0c;下面分…

基于Java校园跑腿管理系统设计与实现(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

《SQL必知必会第五版》第十五章(插入数据)挑战题

1. 使用 INSERT 和指定的列&#xff0c;将你自己添加到 Customers 表中。明确列出要添加哪几列&#xff0c;且仅需列出你需要的列。 INSERT INTO Customers(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country,cust_contact,cust_email) VALUES(…

简单函数_加减乘除

任务描述 对输入的算式进行简单的运算&#xff0c;输出算式结果。运算符只会是加、减-、乘*、除/、求余%、阶乘&#xff01;之一。 输出运算的结果&#xff0c;如果出现除数为零&#xff0c;则输出“error”,如果求余运算的第二个运算数为0&#xff0c;也输出“error”。 输入…

自定义collate_fn函数:应对报错RuntimeError: stack expects each tensor to be equal size

使用BERT或ResNet分别生成文本和图像特征时,由于文本自身长度和图像大小的限制,导致最后形成的特征数据在送入DataLoader时会因为维度不同而报错: RuntimeError: stack expects each tensor to be equal size此时就需要自定义collate_fn函数实现数据的自定义加载功能,下面…

UR5 机器人 URDF 代码阅读

系列文章目录 文章目录 系列文章目录前言一、UR5 URDF 代码二、base_link三、shoulder_pan_joint四、shoulder_pan_trans五、ROS base_link 坐标系到 UR 机器人 Base 坐标系的转换六、与全零TCP&#xff08;工具坐标系&#xff09;重合的工具链接 前言 一、UR5 URDF 代码 <…

算法人生(8):从“注意力算法”看“战胜拖延”(被分心太多版)

现代人拖延产生的原因有很多&#xff0c;比如因为害怕失败而拖延&#xff0c;因为完美主义倾向而拖延&#xff0c;不想走出“舒适区”而拖延等等&#xff0c; 今天我们要针对一个常见的原因“被分心的事情太多”而产生的拖延来看&#xff0c;如何从“注意力算法”的思路中找到些…

类型双关联合体(C++基础)

类型双关 类型双关就是在同样的一个内存中&#xff0c;存储的数据可以用做不同类型的表述。用在底层性能优化的时候&#xff0c;一般使用的时候要非常小心&#xff0c;因为不当的使用可能导致程序的不稳定和不可预测的行为。 int a 5;//double value (double)a;double value…

软考信息系统项目管理师2024上半年报名流程及注意事项

2024年5月软考信息系统项目管理师报名入口&#xff1a; 中国计算机技术职业资格网&#xff08;http://www.ruankao.org.cn/&#xff09; 2024年软考报名时间暂未公布&#xff0c;考试时间上半年为5月25日到28日&#xff0c;下半年考试时间为11月9日到12日。不想错过考试最新消…

Qt Design Studio 软件怎么用(详细+通俗+有趣)

建议&#xff1a;本文长期更新&#xff0c;建议点赞/收藏&#xff01; 1. 啥是Qt Design Studio&#xff1f; Qt Design Studio 是一个用于设计和开发用户界面的工具&#xff0c;特别适合开发跨平台应用程序。它结合了UI设计和开发的工作流程&#xff0c;使得设计师和开发者可…

桌面显示器PD芯片:引领桌面显示技术的新篇章

随着科技的飞速发展&#xff0c;桌面显示器作为人们日常工作与生活中不可或缺的重要设备&#xff0c;其性能与品质也在不断提升。其中&#xff0c;PD芯片作为桌面显示器中的核心组件&#xff0c;发挥着至关重要的作用。本文将对桌面显示器PD芯片进行详细介绍&#xff0c;探讨其…