融云 SDK 消息结构详解

    本文档将详细介绍融云的 SDK 消息体系结构,以便于您更深入的了解融云并更快速的开发自己的产品。

    会话与消息的关系

    融云 Android、iOS、桌面版 SDK 中已经默认包含了消息数据的本地存储机制,开发者不再需要自己进行消息的存储。也就是说,在融云 SDK 收到消息后,先在本地进行了数据存储,然后再通过消息接收事件通知给开发者。开发者可以通过一系列接口读取和操作本地存储的消息数据。

    会话实体和消息实体

    会话实体类和消息实体类是用来存储本地会话和消息的容器类,除了包含会话内容和消息内容外,还包括了保存在本地的各种状态。

    用来存储消息的实体类主要有 Conversation(会话) 和 Message(消息) 两个实体类,您在客户端读取消息时,获取的对象都和这两个类相关。会话有多种类型,可以是私聊会话,也可以是群组会话等,每一个 Conversation(会话)包含多条 Message(消息),关系如下图所示:

    image

    如何标识一个会话

    通过 conversationType 和 targetId,可以唯一确定一个会话。ConversationType 枚举值意义和对应的 targetId 意义为:

    会话名称 会话类型枚举 ConversationType 对应的 targetId
    单聊 PRIVATE 用户的 Id(userId)
    群组 GROUP 群组的 Id(groupId)
    聊天室 CHATROOM 聊天室的 Id(chatroomId)
    客服 CUSTOMER_SERVICE 客服的 Id(customerServiceId)
    系统会话 SYSTEM 系统账户 Id。可以理解为 QQ 的 10000 号的角色
    应用公众服务 APP_PUBLIC_SERVICE 应用公众服务的 Id(publicServiceId)
    公众服务 PUBLIC_SERVICE 公众服务的 Id(publicServiceId)
    请注意区分会话类型和消息类型,会话类型是针对会话的分类,不同的会话类型决定了不同的会话逻辑。

    另:系统会话类型并不一定代表是“系统消息”,本质上与单聊会话类型没有区别,只是逻辑上做了不同的区分,便于展开不同的产品业务逻辑。

    消息的定义

    消息类(MessageContent 的子类)不同于消息实体类(Message),消息类代表一条具体的消息内容,消息实体类是消息类的外层容器,消息实体对象是消息对象在本地存储的外层对象,消息实体对象除了包含消息对象外,还包括消息的方向、接收状态、接收时间、发送者等。

    融云单条消息大小不超过 128k

    消息基类

    MessageContent 是融云的消息基类,所有消息类都继承于 MessageContent 类。需要注意的是,MessageContent 类和 Message 类之间的关系:Message 中包含了一个具体的继承自 MessageContent 的消息,就是 Content 属性,可以通过 setContent() 和 getContent() 进行存取。

    约定:如果您要定义一个内容类消息(需要显示在聊天会话界面中,且不是通知类消息),请从 MessageContent 类继承,命名为 XxxxxMessage。

    内容消息表示一个用户间发送的包含具体内容的消息,需要展现在聊天界面上,如文字消息、语音消息等。

    消息的分类

    消息分类 消息行为状态标识
    内容类消息 表示一个用户间发送的包含具体内容的消息,需要展现在聊天界面上,如文字消息、语音消息等。
    通知类消息 表示一个通知信息,可能展现在聊天界面上,如提示条通知。
    状态类消息 表示一个状态,用来实现如“对方正在输入”的功能。

    内容类消息

    消息类型 ObjectName 类名 是否计数 是否存储
    文字消息 RC:TxtMsg TextMessage
    语音消息 RC:VcMsg VoiceMessage
    图片消息 RC:ImgMsg ImageMessage
    图文消息 RC:ImgTextMsg RichContentMessage
    文件消息 RC:FileMsg FileMessage
    位置消息 RC:LBSMsg LocationMessage
    小视频消息 RC:SightMsg SightMessage
    公众服务单图文消息 RC:PSImgTxtMsg PublicServiceRichContentMessage
    公众服务多图文消息 RC:PSMultiImgTxtMsg PublicServiceMultiRichContentMessage

    注:为了符合 iOS 平台的命名规则,在 iOS SDK 中类名前增加 RC 前缀,如:RCTextMessage。

    通知类消息

    消息类型 ObjectName 类名 是否计数 是否存储
    好友通知消息 RC:ContactNtf ContactNotificationMessage
    资料通知消息 RC:ProfileNtf ProfileNotificationMessage
    通用命令通知消息 RC:CmdNtf CommandNotificationMessage
    提示条通知消息 RC:InfoNtf InformationNotificationMessage
    群组通知消息 RC:GrpNtf GroupNotificationMessage
    已读通知消息 RC:ReadNtf ReadReceiptMessage
    公众服务命令消息 RC:PSCmd PublicServiceCommandMessage
    命令消息 RC:CmdMsg CommandMessage

    注:为了符合 iOS 平台的命名规则,在 iOS SDK 中类名前增加 RC 前缀,如:RCCommandMessage。

    状态类消息

    消息类型 ObjectName 类名 是否计数 是否存储
    对方正在输入状态消息 RC:TypSts TypingStatusMessage

    注:为了符合 iOS 平台的命名规则,在 iOS SDK 中类名前增加 RC 前缀,如:RCTypingStatusMessage。

    是否计数:表示客户端收到消息后,是否进行未读消息计数(未读消息数增加 1),所有内容型消息都应该设置此值。
    是否存储:表示客户端收到消息后,是否进行存储,并在之后可以通过接口查询。

    内置内容类消息

    文字消息

    用来发送文字类消息,其中可以包括表情、超链接(会自动识别),客户端收到消息后计入未读消息数、进行存储。

    消息类名:TextMessage

    消息 ObjectName:RC:TxtMsg

    消息的结构:

    {
      "content":"Hello world!",
      "extra":""
    }
    
    名称 说明
    content 文字消息的文字内容,包括表情。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    语音消息

    用来发送语音片段消息,语音时长上限为 60 秒,客户端收到消息后计入未读消息数、进行存储。

    消息类名:VoiceMessage

    消息 ObjectName:RC:VcMsg

    消息的结构:

    {
      "content":"bhZPzJXimRwrtvc=",
      "duration":7,
      "extra":""
    }
    
    名称 说明
    content 语音内容,格式为 AMR,以 Base64 进行 Encode 后需要将所有 \r\n\r\n 替换成空,大小建议不超过 60k。
    duration 语音消息的时长,最长为 60 秒(单位:秒)。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    图片消息

    用来发送图片类消息,客户端收到消息后计入未读消息数、进行存储。

    消息类名:ImageMessage

    消息 ObjectName:RC:ImgMsg

    消息的结构:

    {
      "content":"bhZPzJXimRwrtvc=",
      "imageUri":"http://p1.cdn.com/fds78ruhi.jpg",
      "isFull":false,
      "extra":""
    }
    
    名称 说明
    content 图片缩略图,格式为 JPG,大小建议不超过 30k,注意在 Base64 进行 Encode 后需要将所有 \r\n\r\n 替换成空。
    imageUri 图片上传到图片存储服务器后的地址。
    isFull 是否发送原图,true 发送原图、false 不发送原图,Web SDK 中没有此属性。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    缩略图最大尺寸为:240 x 240 像素,以宽度和高度中较长的边不超过 240 像素等比压缩。

    大图最大尺寸为:960 x 960 像素,以宽度和高度中较长的边不超过 960 像素等比压缩。

    图片消息包括两个主要部分:缩略图和大图,如设置为原图发送则为缩略图和原图,缩略图直接 Base64 编码后放入 content 中,大图或原图首先上传到文件服务器(融云 SDK 中默认上传到七牛云存储),然后将云存储上的大图或原图地址放入消息体中。流程示意如下:

    App -> App: 压缩原图到大图尺寸,如设置发送为原图则不进行压缩 App -> File Server: 上传大图或原图 File Server --> App: 返回上传大图或原图的地址 App -> App: 压缩大图到缩略图并进行 Base64 转码 App -> RongCloud IM Server: 发送图片消息(内附缩略图内容和大图或原图地址)

    图文消息

    用来发送图文消息,包含一个标题,一段文字内容和一张图片,客户端收到消息后计入未读消息数、进行存储。

    消息类名:RichContentMessage

    消息 ObjectName:RC:ImgTextMsg

    消息的结构:

    {
      "title":"标题",
      "content":"消息描述",
      "imageUri":"http://p1.cdn.com/fds78ruhi.jpg",
      "url":"http://www.rongcloud.cn",
      "extra":""
    }
    
    名称 说明
    title 消息的标题。
    content 消息的文字内容。
    imageUri 消息中图片地址,图片尺寸为:120 x 120 像素。
    url 点击图片消息后跳转的 URL 地址。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    位置消息

    用来发送地理位置消息,客户端收到消息后计入未读消息数、进行存储。

    消息类名:LocationMessage

    消息 ObjectName:RC:LBSMsg

    消息的结构:

    {
      "content":"bhZPzJXimRwrtvc=",
      "latitude":39.9139,
      "longitude":116.3917,
      "poi":"北京市朝阳区北苑路北辰泰岳大厦",
      "extra":""
    }
    
    名称 说明
    content 表示位置图片缩略图,格式为 JPG,以 Base64 进行 Encode 后需要将所有 \r\n\r\n 替换成空。
    latitude 位置的纬度值。
    longitude 位置的经度值。
    poi 表示位置的 poi 信息。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    文件消息

    用来发送文件类消息,客户端收到消息后计入未读消息数、进行存储。

    消息类名:FileMessage

    消息 ObjectName:RC:FileMsg

    消息的结构:

    {
      "name":"file.txt",
      "size":190184,
      "type":"txt",
      "fileUrl":"http://www.demo.com/am.ind",
      "extra":""
    }
    
    名称 说明
    name 文件名称。
    size 文件大小,单位:bytes。
    type 文件类型。
    fileUrl 文件地址。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    小视频消息

    用来发送小视频消息,客户端收到消息后计入未读消息数、进行存储。

    消息类名:SightMessage

    消息 ObjectName:RC:SightMsg

    消息的结构:

    {
      "sightUrl":"http://rongcloud...com/video...",
      "content":"/9j/4AAQSkZ/2wB...hDSaSiimB//9k=",
      "duration":2,
      "size":734320,
      "name":"video_xx.mp4"
    }
    
    名称 说明
    sightUrl 上传到文件服务器的小视频地址。
    content 小视频首帧的缩略图进行 Base64 编码的结果值,格式为 JPG,注意在 Base64 进行 Encode 后需要将所有 \r\n 和 \r 和 \n 替换成空。
    duration 视频时长,单位:秒。
    size 视频大小单位 bytes。
    name 发送端视频的文件名,小视频文件格式为 .mp4
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    公众服务单图文消息

    用来发送单图文消息,客户端收到消息后计入未读消息数、进行存储。

    消息类名:PublicServiceRichContentMessage

    消息 ObjectName:RC:PSImgTxtMsg

    消息的结构:

    {   
      "articles": [
           {
               "title":"即时通讯云就是融云",
               "description":"内容描述",
               "url":"http://www.rongcloud.cn",
               "picurl":"https://www.xxx.com/0416%2F1523835183798.jpeg"
           }
      ],
      "extra":""
    }
    
    名称 说明
    articles 单图文消息内容结构。
    title 消息标题。
    description 图文的描述内容。
    url 图文消息点击后的连接地址。
    picurl 图文消息缩略图地址。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    公众服务多图文消息

    用来发送多图文消息,客户端收到消息后计入未读消息数、进行存储。

    消息类名:PublicServiceMultiRichContentMessage

    消息 ObjectName:RC:PSMultiImgTxtMsg

    消息的结构:

    {   
        "title": "两会记者问答: 区块链蛮创新",
        "articles": [
             {
                 "title":"即时通讯云就是融云",
                 "description":"内容描述",
                 "url":"http://www.rongcloud.cn",
                 "picurl":"https://www.xxx.com/0416%2F1523835183798.jpeg"
             },
             {
                 "title":"即时通讯云就是融云",
                 "description":"内容描述",
                 "url":"http://www.rongcloud.cn",
                 "picurl":"https://www.xxx.com/0416%2F1523835183798.jpeg"
             }
             ],
        "extra":""
    }
    
    名称 说明
    title 多图文消息中,主标题。
    articles 多图文中单个图文数组,最多支持 10 个单图文。
    title 单个图文标题。
    description 图文的描述内容。
    url 图文消息点击后的连接地址。
    picurl 图文消息缩略图地址。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    内置通知类消息

    提示小灰条通知消息

    用来发送在聊天会话页面显示的提示条(小灰条)通知,客户端收到消息后进行存储,不计入未读消息数,此类型消息没有 Push 通知。

    消息类名:InformationNotificationMessage

    消息 ObjectName:RC:InfoNtf

    消息的结构:

    {
      "message":"请在聊天中注意人身财产安全",
      extra:""
    }
    
    名称 说明
    message 提示条消息内容。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    联系人(好友)通知消息

    用来发送联系人操作(加好友等)的通知消息,客户端收到消息后进行存储,不计入未读消息数,此类型消息没有 Push 通知。

    消息类名:ContactNotificationMessage

    消息 ObjectName:RC:ContactNtf

    消息的结构:

    {
      "operation":"Request",
      "sourceUserId":"123",
      "targetUserId":"456",
      "message":"我是小艾,能加一下好友吗?",
      "extra":""
    }
    
    名称 说明
    operation 联系人操作的指令,官方针对 operation 属性定义了 "Request", "AcceptResponse", "RejectResponse" 几个常量,也可以由开发者自行扩展。
    sourceUserId 发出通知的用户 Id。
    targetUserId 单聊会话为接收通知的用户 Id,群聊、聊天室会话为会话 Id。
    message 表示请求或者响应消息,如添加理由或拒绝理由。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    资料通知消息

    用来发送用户资料变更通知消息,客户端收到消息后进行存储,不计入未读消息数,此类型消息没有 Push 通知。

    消息类名:ProfileNotificationMessage

    消息 ObjectName:RC:ProfileNtf

    消息的结构:

    {
      "operation":"Update",
      "data":"{\"nickname\":\"韩梅梅\", \"hometown\":\"beijing\"}",
      "extra":""
    }
    
    名称 说明
    operation 资料通知操作,可以自行定义。
    data 操作的数据。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    通用命令通知消息

    用来发送通用的指令通知消息,消息内可以定义任意 JSON 内容,客户端收到消息后进行存储,不计入未读消息数,此类型消息没有 Push 通知。

    消息类名:CommandNotificationMessage

    消息 ObjectName:RC:CmdNtf

    消息的结构:

    {
      "name":"AtPerson",
      "data":"{\"sourceId\":\"9527\"}"
    }
    
    名称 说明
    name 命令名称,可以自行定义。
    data 命令的内容。

    群组通知消息

    用来发送群组操作的通知消息,客户端收到消息后进行存储,不计入未读消息数,此类型消息没有 Push 通知。

    消息类名:GroupNotificationMessage

    消息 ObjectName:RC:GrpNtf

    消息的结构:

    {
      "operatorUserId":"4324",
      "operation":"Rename",
      "data":"群组中各种通知的操作数据",
      "message":"修改本群名为本地生活",
      "extra":""
    }
    
    名称 说明
    operatorUserId 操作人用户 Id。
    operation 操作名称,可以自行定义。
    data 群组中各种通知的操作数据,详见“群组通知消息结构数据说明”。
    message 消息内容。
    extra 扩展信息,可以放置任意的数据内容,也可以去掉此属性。

    群组通知消息结构数据说明

    使用 IMKit SDK 进行集成,融云内置的群组操作通知消息结构 JOSN 格式如下:

    操作 示例说明 JSON 说明
    创建群组 {
        "operatorUserId":"4324",
        "operation":"Create",
        "data":"{
            "operatorNickname":"李天",
            "targetGroupName":"群名"
          }",
        "message":"创建群组",
        "extra":""
    }
    operatorUserId 为操作人用户 Id
    operation 为操作名
    data 数据说明: operatorNickname 为操作者,targetGroupName 为群名称
    修改群名称 {
        "operatorUserId":"4324",
        "operation":"Rename",
        "data":"{
            "operatorNickname":"李天",
            "targetGroupName":"群名"
          }",
        "message":"修改群名称",
        "extra":""
    }
    operatorUserId 为操作人用户 Id
    operation 为操作名
    data 数据说明:operatorNickname 为操作者,targetGroupName 为群名称
    添加群成员 {
        "operatorUserId":"4324",
        "operation":"Add",
        "data":"{
            "operatorNickname":"李天",
            "targetUserIds":["wGPkc0"],
            "targetUserDisplayNames":["腾飞"]
          }",
        "message":"添加群成员",
        "extra":""
    }
    operatorUserId 为操作人用户 Id
    operation 为操作名
    data 数据说明:operatorNickname 为操作者
    targetUserIds 为被加入群的用户 ID
    targetUserDisplayNames 为被加入群的用户与 targetUserIds 相对应。
    移出群成员 {
        "operatorUserId":"4324",
        "operation":"Kicked",
        "data":"{
            "operatorNickname":"李天",
            "targetUserIds":["wGPkc0"],
            "targetUserDisplayNames":["腾飞"]
          }",
        "message":"移出群成员",
        "extra":""
    }
    operatorUserId 为操作人用户 Id
    operation 为操作名
    data 数据说明:operatorNickname 为操作者
    targetUserIds 为被移出群的用户 ID
    targetUserDisplayNames 为被移出群的用户名与 targetUserIds 相对应。
    退出群组 {
        "operatorUserId":"4324",
        "operation":"Quit",
        "data":"{
            "operatorNickname":"李天",
            "targetUserIds":["wGPkc0VpO"],
            "targetUserDisplayNames":["腾飞"],
            "newCreatorId":"newCreatorId"
          }",
        "message":"退出群组",
        "extra":""
    }
    operatorUserId 为操作人用户 Id
    operation 为操作名
    data 数据说明:operatorNickname 为操作者,targetUserIds 为操作者 ID ,targetUserDisplayNames 为操作者
    newCreatorId 如退出群的用户为群创建者则 newCreatorId 为新的群创建者 ID ,否则为 null。
    解散群组 {
        "operatorUserId":"4324",
        "operation":"Dismiss",
        "data":"{
            "operatorNickname":"李天"
          }",
        "message":"解散群组",
        "extra":""
    }
    operatorUserId 为操作人用户 Id
    operation 为操作名
    data 数据说明:operatorNickname 为操作者。
    如你使用的是 IMLib SDK 进行集成则群组通知消息结构中 data 数据需要自行定义。

    已读通知消息

    用来发送消息已经被接收到的状态消息,客户端收到消息后不计入未读消息数、不存储,此类型消息没有 Push 通知。

    消息类名:ReadReceiptMessage

    消息 ObjectName:RC:ReadNtf

    消息的结构:

    {
      "lastMessageSendTime":1408706337,
      "messageUId":"XXXXXX",
      "type":1
    }
    
    名称 说明
    lastMessageSendTime 最后一条消息的发送时间。
    messageUId 最后一条消息的 UId。
    type 消息类型。

    公众服务命令消息

    公众服务中用来发送通用的指令通知消息,消息内可以定义任意 JSON 内容,客户端收到消息后不计入未读消息数、不存储。

    消息类名:PublicServiceCommandMessage

    消息 ObjectName:RC:PSCmd

    消息的结构:

    {
      "cmd":"AtPerson",
      "data":"{\"sourceId\":\"9527\"}"
    }
    
    名称 说明
    cmd 命令名称,可以自行定义。
    data 命令的内容。

    命令消息

    用来发送通用的指令通知消息,消息内可以定义任意 JSON 内容,与通用命令通知消息的区别是不存储、不计数,此类型消息没有 Push 通知。

    消息类名:CommandMessage

    消息 ObjectName:RC:CmdMsg

    消息的结构:

    {
      "name":"AtPerson",
      "data":"{\"sourceId\":\"9527\"}"
    }
    
    名称 说明
    name 命令名称,可以自行定义。
    data 命令的内容。

    内置状态类消息

    对方正在输入状态消息

    用来发送对方正在输入时的状态消息,客户端收到消息后不计入未读消息数、不存储。

    消息类名:TypingStatusMessage

    消息 ObjectName:RC:TypSts

    消息的结构:

    {
      "typingContentType":"RC:TxtMsg"
    }
    
    名称 说明
    typingContentType 正在输入消息类型。