IM系统中聊天记录模块的设计与实现

简介:   看到很多开发IM系统的朋友都想实现聊天记录存储和查询这一不可或缺的功能,这里我就把自己前段时间为傲瑞通(OrayTalk)开发聊天记录模块的经验分享出来,供需要的朋友参考下。 一.总体设计 1.存储位置     从一开始我们就打算在服务端和客户端本地同时存储聊天记录,而且,在客户端查看聊天记录时,可以选择是从本地加载、还是从服务器加载。

  看到很多开发IM系统的朋友都想实现聊天记录存储和查询这一不可或缺的功能,这里我就把自己前段时间为傲瑞通(OrayTalk)开发聊天记录模块的经验分享出来,供需要的朋友参考下。

一.总体设计

1.存储位置  

  从一开始我们就打算在服务端和客户端本地同时存储聊天记录,而且,在客户端查看聊天记录时,可以选择是从本地加载、还是从服务器加载。这样做的好处有两个:

(1)从本地加载聊天记录速度非常快。

(2)当更换了登录的机器,在任何地方任何时刻都可以从服务器加载完整的聊天记录,记录永远不会丢失。

2.存储方案

(1)在服务端存储聊天记录当然使用我们主流的数据库SqlServer或Mysql等。

(2)在客户端,我们开始选择的是使用序列化技术,但是,考虑到当聊天记录数据量庞大时,序列化方案就不够灵活了,而且性能也跟不上。所以,最后决定使用轻量级的数据库Sqlite。

3.ORM框架

  DataRabbit的最新版本增加了对Sqlite的支持,并且对不同数据库的操作API是完全一致的,所以我们使用DataRabbit写了一个小组件来完成聊天记录的存储与查询等数据库访问操作。而无论是客户端还是服务端的聊天记录存储相关的工作,都交给这个组件来完成。

 

二.具体实现

1.ChatMessageRecord类

  一条聊天记录基本上包含了以下几个内容:发送人、接收人、内容、时间等。并且,我们想将两人聊天及群聊天抽象成同一个模型,于是,聊天记录的Entity类ChatMessageRecord设计成如下模样:

    public class ChatMessageRecord
    {     
        #region AutoID
        private long autoID = 0;
        /// <summary>
        /// 自增ID,编号。
        /// </summary>
        public long AutoID
        {
            get { return autoID; }
            set { autoID = value; }
        }
        #endregion

        #region SpeakerID
        private string speakerID = "";
        /// <summary>
        /// 发言人的ID。
        /// </summary>
        public string SpeakerID
        {
            get { return speakerID; }
            set { speakerID = value; }
        }
        #endregion

        #region AudienceID
        private string audienceID = "";
        /// <summary>
        /// 听众ID,可以为GroupID。
        /// </summary>
        public string AudienceID
        {
            get { return audienceID; }
            set { audienceID = value; }
        }
        #endregion

        #region OccureTime
        private DateTime occureTime = DateTime.Now;
        /// <summary>
        /// 聊天记录发生的时间。
        /// </summary>
        public DateTime OccureTime
        {
            get { return occureTime; }
            set { occureTime = value; }
        }
        #endregion

        #region ContentRtf
        private string contentRtf = "";
        /// <summary>
        /// 聊天的内容。
        /// </summary>
        public string ContentRtf
        {
            get { return contentRtf; }
            set { contentRtf = value; }
        }
        #endregion

        #region IsGroupChat
        private bool isGroupChat = false;
        /// <summary>
        /// 是否为群聊记录。
        /// </summary>
        public bool IsGroupChat
        {
            get { return isGroupChat; }
            set { isGroupChat = value; }
        }
        #endregion
    } 

    在ChatMessageRecord的定义中,聊天内容字段被设计为string类型,这是因为在OrayTalk中,聊天内容是富文本RTF格式的。如果需要,可以更改为byte[]类型,这样通过自定义的序列化操作就可以承载更复杂的聊天格式。

  最后一个字段IsGroupChat表明当前记录是否为群聊记录,如果是群聊记录,那么,AudienceID就不是好友的ID了,而是目标群组的ID。

  最后请注意:ChatMessageRecord实体与数据库中的ChatMessageRecord表是完全映射的关系,这才使得DataRabbit的ORM数据访问成为可能。

2.ChatRecordPage类

  当我们请求聊天记录时,由于记录数量可能非常庞大,所以,采用分页是不可避免的。我们用ChatRecordPage来封装查询返回的一页聊天记录:

根据ChatRecordPage中的TotalCount字段,查询者可以知道符合条件的记录数是多少,如此,就可以知道总共有多少页。

3.IChatRecordPersister接口

  无论是客户端还是服务端存储与查询聊天记录,我们都使用同一个接口IChatRecordPersister来进行抽象:

    public interface IChatRecordPersister
    {
        /// <summary>
        /// 插入一条聊天记录(包括群聊天记录)。
        /// </summary>  
        void InsertChatMessageRecord(ChatMessageRecord record);

        
        /// <summary>
        /// 获取一页与好友的聊天记录。
        /// </summary>
        /// <param name="timeScope">日期范围</param>
        /// <param name="myID">自己的UserID</param>
        /// <param name="friendID">好友的ID</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="pageIndex">页索引</param>      
        /// <returns>聊天记录页</returns>
        ChatRecordPage GetChatRecordPage(DateTimeScope timeScope, string myID, string friendID, int pageSize, int pageIndex);

        /// <summary>
        /// 获取一页群聊天记录。
        /// </summary>
        /// <param name="timeScope">日期范围</param>
        /// <param name="groupID">群ID</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="pageIndex">页索引</param>     
        /// <returns>聊天记录页</returns>
        ChatRecordPage GetGroupChatRecordPage(DateTimeScope timeScope, string groupID, int pageSize, int pageIndex);        
    }

(1)插入游戏记录时,与好友聊天记录以及群聊天记录使用同一个InsertChatMessageRecord方法即可,只是在构造ChatMessageRecord对象时,字段的赋值有所区别。

(2)使用DataRabbit实现该接口时(如ChatRecordPersister类),通过属性DataBaseType来控制访问的是否为Sqlite数据库。然后在服务端使用ChatRecordPersister存取聊天记录时,就将DataBaseType设置为SqlServer;客户端则设置为Sqlite。

 

三.可能的Remoting的接口

  当我们从服务器加载聊天记录时,可以考虑使用Remoting技术来实现,如果是这样,只需要在服务端把IChatRecordPersister接口暴露为Remoting服务,然后客户端使用这一Remoting服务进行聊天记录查询。这样一来,客户端在切换从本地加载和从服务器加载时,只需要切换IChatRecordPersister为本地ChatRecordPersister对象的引用或remoting远程引用即可。整个的代码实现将会非常简洁一致。

  到这里,关于聊天记录模块的设计与实现就介绍得差不多了,依照这样的思路,大家在自己的IM系统中增加聊天记录的功能应该是很简单的了。最后,上一张OrayTalk客户端查询聊天记录界面的截图:

      

 就到这里了,还有疑问的朋友,请给我留言,我会及时回复的。

 

目录
相关文章
|
1月前
|
存储 自然语言处理 机器人
实战揭秘:当RAG遇上企业客服系统——从案例出发剖析Retrieval-Augmented Generation技术的真实表现与应用局限,带你深入了解背后的技术细节与解决方案
【10月更文挑战第3天】随着自然语言处理技术的进步,结合检索与生成能力的RAG技术被广泛应用于多个领域,通过访问外部知识源提升生成内容的准确性和上下文一致性。本文通过具体案例探讨RAG技术的优势与局限,并提供实用建议。例如,一家初创公司利用LangChain框架搭建基于RAG的聊天机器人,以自动化FAQ系统减轻客服团队工作负担。尽管该系统在处理简单问题时表现出色,但在面对复杂或多步骤问题时存在局限。此外,RAG系统的性能高度依赖于训练数据的质量和范围。因此,企业在采用RAG技术时需综合评估需求和技术局限性,合理规划技术栈,并辅以必要的人工干预和监督机制。
96 3
|
1月前
|
人工智能 自然语言处理 搜索推荐
AI技术在智能客服系统中的应用与挑战
【9月更文挑战第32天】本文将探讨AI技术在智能客服系统中的应用及其面临的挑战。我们将分析AI技术如何改变传统客服模式,提高服务质量和效率,并讨论在实际应用中可能遇到的问题和解决方案。
244 65
|
18天前
|
人工智能 自然语言处理 搜索推荐
选型攻略 | 智能客服系统该怎么选?(好用的智能客服系统推荐)
智能客服系统的选型需要综合考虑渠道功能、系统性能、客服工作管理、客户管理以及成本效益等因素。目前合力亿捷推出的智能知识库,梳理海量知识,根据不同主题对知识进行分类,使其结构更清晰。
49 0
|
18天前
|
人工智能 自然语言处理 安全
AI技术在智能客服系统中的应用与挑战
【10月更文挑战第28天】本文将深入探讨人工智能(AI)技术在智能客服系统中的应用及其面临的挑战。我们将通过实例分析,了解AI如何改善客户服务体验,提高效率和降低成本。同时,我们也将关注AI在实际应用中可能遇到的问题,如语义理解、情感识别和数据安全等,并提出相应的解决方案。
|
1月前
|
存储 安全 开发工具
百度公共IM系统的Andriod端IM SDK组件架构设计与技术实现
本文主要介绍了百度公共IM系统的Andriod端IM SDK的建设背景、IM SDK主要结构和工作流程以及建设过程遇到的问题和解决方案。
55 3
|
2月前
|
数据挖掘 API
如何选择适合的售后工单管理系统
选择合适的售后工单管理系统需评估需求和预算,考察功能、技术支持及服务商可靠性,并全面试用评估。ZohoDesk适合初创和中小企业,具备强大的工单管理、报告分析及可定制性,助力提升服务质量和客户体验。通过合适系统,企业不仅能优化客户服务流程,还能通过数据分析支持决策,推动长远发展。
64 16
|
2月前
|
人工智能 自然语言处理 前端开发
从客服场景谈:大模型如何接入业务系统
本文探讨了大模型在AI客服中的应用。大模型虽具有强大的知识生成能力,但在处理具体业务如订单咨询、物流跟踪等问题时,需结合数据库查询、API调用等手段。文章提出用Function Call连接大模型与业务系统,允许大模型调用函数获取私域知识。通过具体示例展示了如何设计系统提示词、实现多轮对话、定义Function Call函数,并利用RAG技术检索文档内容。最后,展示了该方案在订单查询和产品咨询中的实际效果。
|
1月前
|
前端开发 JavaScript PHP
Thinkphp在线客服系统源码多语言外贸版_PHP客服系统源码Uniapp开发搭建+论文设计
Thinkphp在线客服系统源码多语言外贸版_PHP客服系统源码Uniapp开发搭建+论文设计
|
1月前
|
人工智能 算法 搜索推荐
选择智能工单系统的理由,功能与效益分析
智能工单管理系统利用数字化技术,帮助企业高效接收、分配和解决客户请求,具备多渠道接收、智能分配和自动化处理等功能。通过实时响应、数据分析和协作工具,系统显著提升服务质量和效率,优化客户体验,成为企业提升竞争力的关键工具。Zoho Desk等系统表现尤为突出,支持多种渠道和服务功能,助力企业实现高效管理。
49 0
|
2月前
|
机器学习/深度学习 自然语言处理 搜索推荐
探索深度学习与自然语言处理(NLP)在智能客服系统中的创新应用
探索深度学习与自然语言处理(NLP)在智能客服系统中的创新应用
190 0

热门文章

最新文章

下一篇
无影云桌面