3.聊天消息树协议设计

  1. 3.聊天消息树协议设计
    1. 3.1 知识点
      1. 设计思路
      2. 消息树结构与属性定义图
      3. 面向对象类图
      4. 核心伪代码示例
      5. 小结

3.聊天消息树协议设计


3.1 知识点

设计思路

聊天消息树(ChatInfoTree)是一种通用的聊天传输格式,是客户端与服务器之间唯一的聊天协议载体。双端都有这些代码。通过消息树,你可以轻松地:

  • 定义频道与目标:设置 ChatChannelTypeChatChannelId,并指定一个或多个接收目标 Target
  • 组织丰富内容:按顺序拼接任意类型的节点(文字、表情、链接、位置、打开 UI、装备信息等),每个节点都可携带交互事件。
  • 自定义展示:客户端解析后,可根据节点类型自由渲染,支持富文本、高亮、点击跳转、地图定位等效果。

这种设计不仅让消息格式高度模块化、可扩展,还保证了客户端与服务器对协议的完全一致,使得新增节点类型、改动展示逻辑都能在不破坏兼容性的前提下平滑迭代。

消息树结构与属性定义图

classDiagram
  class ChatInfoTree {
    +int ChatChannelType
    +long ChatChannelId
    +long UnitId
    +string UserName
    +bool IsHaveLinkItem
    +long SystemBroadcastId
    +List Target
    +List Nodes
  }

  class ChatInfoNode {
    +int ChatNodeType
    +int ChatNodeEvent
    +string Content
    +string Color
    +byte[] Data
  }

  ChatInfoTree "1" o-- "*" ChatInfoNode : 包含
  • ChatInfoTree

    • ChatChannelType:频道类型(世界 / 私聊 / 公会 / 跑马灯 / …)
    • ChatChannelId:频道 ID(对应组队、公会、地图等)
    • UnitIdUserName:发送者身份
    • IsHaveLinkItem:是否包含可点击的物品或链接(可选)
    • SystemBroadcastId:系统广播配置 ID(可选)
    • Target:定向接收者列表(私聊或部分广播)
    • Nodes:按顺序存放的消息节点列表
  • ChatInfoNode

    • ChatNodeType:节点类型(Text / Link / Image / OpenUI / Position / Item …)
    • ChatNodeEvent:点击或交互事件类型(ClickLink / OpenUI / Position / UseItem …)
    • Content:显示文本或简要描述
    • Color:自定义显示颜色(可选)
    • Data:序列化后的二进制参数(如链接地址、UI 名称、坐标结构等,可选)

面向对象类图

注意:可以直接在消息中传入ChatInfoTree,无需序列化反序列化ChatInfoTree。保证双端有共享聊天数协议即可。当然也可以序列化ChatInfoTree后再接受端再反序列化,这样传递的是字节数组。

classDiagram
  class ChatMessage {
    +ChatInfoTree Tree
    +byte[] Serialize()
    +$static$ ChatMessage Deserialize(byte[])
  }

  class ChatInfoTree {
    +int ChannelType
    +long ChannelId
    +long SenderId
    +string SenderName
    +List~long~ TargetIds
    +List~ChatInfoNode~ Nodes
    +AddText(string)$ ChatInfoTree
    +AddLink(string, string)$ ChatInfoTree
    +AddImage(string)$ ChatInfoTree
    +AddOpenUI(string, string)$ ChatInfoTree
    +AddPosition(string, string, float, float, float)$ ChatInfoTree
  }

  class ChatInfoNode {
    +int NodeType
    +int EventType
    +string Content
    +string Color
    +byte[] Data
  }

  ChatMessage --> ChatInfoTree
  ChatInfoTree "1" o-- "*" ChatInfoNode : contains
  • ChatMessage:负责整条消息的序列化与反序列化。
  • ChatInfoTree:链式 API 构建各类节点,最终生成完整树结构。
  • ChatInfoNode:仅存数据,无行为;所有“添加节点”的方法都由 ChatInfoTree 提供。

核心伪代码示例

// 客户端:构建一条世界聊天,带位置和超链接
var tree = new ChatInfoTree()
    .AddText("我当前在:")
    .AddPosition("龙之谷", "龙之谷地图", 120.5f, 75.2f, 0f)
    .AddText(" 更多信息:")
    .AddLink("点击前往官网", "https://game.example.com");

// 序列化并发送
var msg = new ChatMessage { Tree = tree };
await session.Call(new C2Chat_SendMessageRequest {
    ChatInfoTree = msg.Serialize()
});
// 服务器端:解析并分发
var resp = await session.Call<Chat2C_Message>(req);
var chatMsg = ChatMessage.Deserialize(resp.ChatInfoTree);
foreach (var node in chatMsg.Tree.Nodes) {
    switch ((ChatNodeType)node.NodeType) {
        case ChatNodeType.Text:
            Console.Write(node.Content);
            break;
        case ChatNodeType.Link:
            // 渲染为可点击超链接
            break;
        case ChatNodeType.Position:
            // 绑定地图跳转事件
            break;
        // ……
    }
}
// 频道类型
[Flags]
public enum ChatChannelType {
    None = 0,
    World = 1 << 1,
    Private = 1 << 2,
    System = 1 << 3,
    Broadcast = 1 << 4,
    Notice = 1 << 5,
    Team = 1 << 6,
    Near = 1 << 7,
    CurrentMap = 1 << 8,
    All = World | Private | System | Broadcast | Notice | Team | Near,
    Display = All | CurrentMap
}

// 节点交互事件
public enum ChatNodeEvent {
    None = 0,
    OpenUI = 1,
    OpenLink = 2,
    UseItem = 3,
    Position = 4
}

// 节点类型
public enum ChatNodeType {
    None = 0,
    Position = 1,
    OpenUI = 2,
    Link = 3,
    Item = 4,
    Text = 5,
    Image = 6
}
// 工厂扩展方法(部分示例)
public static class ChatNodeFactory {
    public static ChatInfoTree AddendTextNode(this ChatInfoTree tree, string content) { … }
    public static ChatInfoTree AddendLinkNode(this ChatInfoTree tree, string content, string link) { … }
    public static ChatInfoTree AddendImageNode(this ChatInfoTree tree, string content) { … }
    public static ChatInfoTree AddendOpenUINode(this ChatInfoTree tree, string content, string uiName) { … }
    public static ChatInfoTree AddendPositionNode(this ChatInfoTree tree, string content, string mapName, float x, float y, float z) { … }
}

// 聊天树快捷入口
public static class ChatTreeFactory {
    public static ChatInfoTree World(Scene s) => new() { Scene = s, ChatChannelType = (int)ChatChannelType.World };
    public static ChatInfoTree Private(Scene s) => new() { Scene = s, ChatChannelType = (int)ChatChannelType.Private };
    // … 其它频道 …
}

小结

  1. 统一格式ChatInfoTree + ChatInfoNode 让所有聊天场景都走同一条协议路线。
  2. 链式易用:面向对象的链式 API,让客户端构建消息简单直观。
  3. 事件驱动:节点携带 ChatNodeEvent,可在 UI 层或逻辑层自由绑定交互。
  4. 高度可扩展:新增节点类型或事件,只需扩展枚举和 Factory 方法,无需改动分发/渲染框架。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏