NewLife/NewLife.RocketMQ

chore(release): 准备 v4.0.2026.1024 正式发版

- 主版本升级:NewLife.Core 升级至 12.0.2026.1024(核心网络库跨主版本),程序集版本提升到 4.0.0.0
- 发布流程同时推送 NuGet.org 与 GitHub Packages,并依据 ChangeLog 自动创建 GitHub Release,运行于 Ubuntu
- ChangeLog 新增 v4.0.2026.1024 条目并登记破坏性变更,误置于 v3.2 条目下的十月变更归位
- 补齐 10 个语种 README 的事件总线章节,安装示例版本更新为 4.0.*,重新生成 NuGet 包版 README
- 修复包消费 AOT 冒烟仍比对中文旧文案导致的上限断言失败
大石头 authored at 2026-10-24 12:31:52 大石头 committed at 2026-10-24 12:52:24
7385577
Tree
1 Parent(s) 3c00ae0
Summary: 16 changed files with 581 additions and 52 deletions.
Modified +95 -4
Modified +1 -1
Modified +71 -31
Modified +4 -4
Modified +41 -1
Modified +41 -1
Modified +41 -1
Modified +41 -1
Modified +41 -1
Modified +41 -1
Modified +1 -1
Modified +39 -1
Modified +41 -1
Modified +41 -1
Modified +1 -1
Modified +41 -1
Modified +95 -4
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 1b3a592..6df62a7 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -5,9 +5,14 @@ on:
     tags: [ v* ]
   workflow_dispatch:
 
+# 必须同时声明:缺 packages: write 会让 GitHub Packages 推送 403,缺 contents: write 无法创建 Release
+permissions:
+  contents: write
+  packages: write
+
 jobs:
   build-publish:
-
+    # 优先 Ubuntu:打包与发包均为纯托管流程,无需 Windows 专属工具链
     runs-on: ubuntu-latest
 
     steps:
@@ -21,10 +26,96 @@ jobs:
           8.x
           9.x
           10.x
+    - name: Resolve version
+      id: version
+      # tag 发布时以 tag 为准(去掉 v 前缀),保证包版本与 tag 完全一致;
+      # 手工触发时不传 Version,沿用 csproj 中「主.次.当天」的默认版本
+      run: |
+        if [ "${{ github.ref_type }}" = "tag" ]; then
+          VERSION="${GITHUB_REF_NAME#v}"
+          echo "version=$VERSION" >> "$GITHUB_OUTPUT"
+          echo "pack_args=-p:Version=$VERSION" >> "$GITHUB_OUTPUT"
+        else
+          echo "version=(csproj default)" >> "$GITHUB_OUTPUT"
+          echo "pack_args=" >> "$GITHUB_OUTPUT"
+        fi
     - name: Build
       run: |
-        dotnet pack -c Release -o out NewLife.RocketMQ/NewLife.RocketMQ.csproj
-    - name: Publish
+        dotnet pack -c Release -o out ${{ steps.version.outputs.pack_args }} NewLife.RocketMQ/NewLife.RocketMQ.csproj
+        ls -l out
+    - name: Publish to GitHub Packages
+      id: ghpackages
+      # 备用镜像渠道,失败只告警,不阻断 NuGet.org 正式发布
+      continue-on-error: true
+      run: |
+        dotnet nuget push ./out/*.nupkg --skip-duplicate --source https://nuget.pkg.github.com/NewLifeX/index.json --api-key ${{ github.token }}
+    - name: Publish to NuGet.org
+      id: nuget
       run: |
-        # dotnet nuget push ./out/*.nupkg --skip-duplicate --source https://nuget.pkg.github.com/NewLifeX/index.json --api-key ${{ github.token }}
         dotnet nuget push ./out/*.nupkg --skip-duplicate --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.nugetKey }}
+    - name: Create GitHub Release
+      id: release
+      # 仅 tag 推送时创建;手工触发(无 tag)只发包
+      if: startsWith(github.ref, 'refs/tags/')
+      # 观察期:失败只告警,不影响已完成的发包;结尾 Publish Summary 会显式标红
+      continue-on-error: true
+      env:
+        GH_TOKEN: ${{ github.token }}
+      run: |
+        set -euo pipefail
+        tag="$GITHUB_REF_NAME"
+
+        # 幂等:同 tag 已有 Release 就直接跳过,失败重跑不会报错
+        if gh release view "$tag" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
+          echo "Release $tag 已存在,跳过"
+          exit 0
+        fi
+
+        # 发布说明优先取 ChangeLog.md 中当前版本段落(标题形如 "## v3.3.2026.1024 (2026-10-24)")
+        version="${tag#v}"
+        escaped=$(printf '%s' "$version" | sed 's/[.]/\\./g')
+        start=$(grep -nE "^## v?${escaped}([ (]|\$)" ChangeLog.md | head -1 | cut -d: -f1 || true)
+
+        args=(release create "$tag" --repo "$GITHUB_REPOSITORY" --title "$tag" --verify-tag)
+        if [ -n "$start" ]; then
+          end=$(awk -v s="$start" 'NR>s && /^## /{print NR; exit}' ChangeLog.md)
+          [ -n "$end" ] || end=$(( $(wc -l < ChangeLog.md) + 1 ))
+          sed -n "${start},$((end - 1))p" ChangeLog.md > release-notes.md
+          args+=(--notes-file release-notes.md)
+          echo "发布说明取自 ChangeLog.md 的 $version 段落($((end - start)) 行)"
+        else
+          args+=(--generate-notes)
+          echo "ChangeLog.md 未找到 $version 段落,改用自动生成说明"
+        fi
+
+        shopt -s nullglob
+        assets=(out/*.nupkg out/*.snupkg)
+        args+=("${assets[@]}")
+        gh "${args[@]}"
+        echo "已创建 Release $tag,附加资产 ${#assets[@]} 个"
+    - name: Publish Summary
+      if: always()
+      run: |
+        summary="$GITHUB_STEP_SUMMARY"
+        echo "### 发布结果" >> "$summary"
+        echo "" >> "$summary"
+        echo "| 渠道 | 结果 |" >> "$summary"
+        echo "| --- | --- |" >> "$summary"
+        for row in \
+          "GitHub Packages|${{ steps.ghpackages.outcome }}" \
+          "NuGet.org|${{ steps.nuget.outcome }}" \
+          "GitHub Release|${{ steps.release.outcome }}"
+        do
+          name="${row%%|*}"
+          outcome="${row##*|}"
+          case "$outcome" in
+            success) mark="✅" ;;
+            failure) mark="⚠️" ;;
+            skipped) mark="⏭" ;;
+            cancelled) mark="⛔" ;;
+            *) mark="❔" ;;
+          esac
+          echo "| $name | $mark $outcome |" >> "$summary"
+        done
+        echo "" >> "$summary"
+        echo "> GitHub Release 仅 tag 推送时创建;手工触发只发包。" >> "$summary"
Modified +1 -1
diff --git a/AotPackageSmoke/Program.cs b/AotPackageSmoke/Program.cs
index 3574590..9ad4cad 100644
--- a/AotPackageSmoke/Program.cs
+++ b/AotPackageSmoke/Program.cs
@@ -150,7 +150,7 @@ Check("消息压缩·ZLIB 往返与上限", () =>
     }
     catch (InvalidDataException ex)
     {
-        caught = ex.Message.Contains("上限");
+        caught = ex.Message.Contains("limit");
     }
     Assert(caught, "超出解压上限未按预期拦截");
 });
Modified +71 -31
diff --git a/ChangeLog.md b/ChangeLog.md
index a1b1190..3049028 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,76 @@
 # 更新日志
 
+## v4.0.2026.1024 (2026-10-24)
+
+### 大版本与兼容性
+- **NewLife.Core 12 核心网络库**:本次升级跨越 Core 主版本(消息栈 v12、运行时多语言、NativeAOT),因此本库同步提升主版本号至 4.0;包依赖需一并升级到 NewLife.Core 12
+- **运行时消息英文化**:日志、协议解析异常、公开 API 异常与配置描述改为英文源文,再按 `Localization.Culture` 翻译;依赖中文日志文本做解析或告警匹配的调用方需要调整
+- **gRPC 单向发送语义**:`PublishOneway` 在 gRPC 模式下由抛出 `NotSupportedException` 改为异步模拟(立即返回合成 SendOK,失败仅记录日志)
+- **解压上限放宽**:ZLIB 默认解压上限由 4MB 调整为 64MB,并支持按实例配置
+- **程序集版本**:AssemblyVersion 由 3.2.0.0 提升到 4.0.0.0
+
+### 事件总线
+- **RocketMqEventBus&lt;TEvent&gt;**:新增基于 Core `IEventBus` 契约的事件总线,复用 Producer/Consumer 实现跨进程发布订阅;处理器异常时回投重试直至进入死信队列,解码失败跳过以免毒消息阻塞消费
+- **RocketMqEventBusFactory**:实现 `IEventBusFactory`,按主题创建并缓存总线,支持复用外部客户端与自建客户端两种模式,可直接挂到 `EventHub.Factory`
+- **MqEventBusNaming**:归一化事件主题与消费组名称,避免 `.`/`@` 被 Broker 拒绝,超过 127 字符截断
+
+### 运行时多语言
+- **31 种语言词表**:日志、协议解析异常、公开 API 异常与配置项描述统一使用英文源文,按 `Localization.Culture` 自动翻译并回退英文;带前缀日志先翻译再拼前缀,前缀不参与词表查找
+- **跨文化鲁棒性**:消除区域敏感写法(心跳 `ToUpperInvariant`、ACL 时间戳固定 InvariantCulture、前缀比较改 Ordinal),土耳其语/泰语/阿拉伯语等区域下协议与签名不再变形
+- **词表校验门禁**:CI 校验源码实际使用的键均在词表中,并逐语言逐词条验证运行期命中,避免静默回退英文
+
+### NativeAOT 与裁剪支持
+- **NativeAOT**:net10.0 目标开启 IsAotCompatible,库内序列化改走源生成成员访问器与元数据根,去除反射路径
+- **AOT 对象体登记**:新增公共 API `MqAot.RegisterBodyType<T>()`——实测消费方自定义类型(POCO)消息体在裁剪后会被静默序列化为 `{}`,登记后正常;老目标框架为空实现,多目标工程可共用启动代码
+- **AOT 冒烟**:新增 AotSmoke 控制台工程并扩至 34 用例(帧编解码/请求头/JSON/消息压缩/LMQ/ACL/云厂商/双协议转换/端到端收发/gRPC 链路含死信转发与 FIFO 顺序消费),CI 增加 linux-x64 发布运行步骤
+- **包消费验证**:新增 AotPackageSmoke 工程,以 PackageReference 消费打包产物(区别于工程引用),覆盖包资产与依赖声明、源生成序列化、压缩、ACL 签名与端到端压缩往返;CI 增加 pack + 本地源恢复 + 发布 + 运行步骤
+- **AOT 告警门禁**:AOT 发布统一加 IL2026/IL3050/IL2104 告警阻断并关闭单告警聚合(实测可拦截 IL3050 回归)
+- **发布基线与监控**:新增 scripts/AotBaseline.cs 采集发布体积、启动开销与 CPU 吞吐并支持阈值判定,CI 输出流水线摘要并归档 JSON;win-x64 基线:可执行文件 10.03 MB、启动 47 ms
+- **版本策略**:AssemblyVersion 由 `3.2.*` 通配符改为 `3.2.0.0`(通配符与确定性构建冲突,且程序集版本宜只在发布时递增,FileVersion/PackageVersion 仍用完整日期版本)
+
+### RocketMQ 5.x gRPC 链路与消费语义
+- **Proxy 链路打通**:修复明文 h2c 未强制 HTTP/2、发送缺 MessageId、Telemetry 一次性上报后被注销、缺 grpc-timeout、PushConsumer 缺客户端标识等缺陷;新增 GrpcTelemetrySession 资源上报长连接(周期重建自愈,暴露 ConnectCount/ErrorCount)
+- **消费重试**:失败消息由 Broker 写入 %RETRY%{group}_{topic} 并按 popFromRetryProbability 概率并回原主题的拉取响应,客户端只需消费原主题;不可见时间下限收敛为 10 秒
+- **死信处理**:新增 GrpcPushConsumer.MaxDeliveryAttempts(默认 16)达限转 %DLQ%{group},以及 Consumer.ForwardToDeadLetterQueueViaGrpcAsync、GetGrpcDlqTopic 与死信重投工具 scripts/DlqTool.cs
+- **事务消息**:修正 EndTransaction 的 resolution/source 字段编号错位(此前回滚被当作提交处理),实测提交可见、回滚不可见
+- **FIFO 顺序消费**:新增 Message.MessageGroup 与 GrpcPushConsumer.Orderly,实测并发度 20 下仍严格按发送顺序消费
+- **主题类型**:CreateTopic 的 topicMessageType 改为写入 attributes 的 message.type,FIFO/事务主题可正常创建
+- **ACL 2.0 鉴权**:修正 gRPC 签名输出为十六进制(Proxy 侧先 hex→base64 再比对);实测无凭据、非管理员、错误密钥均被拒,管理员账户可正常收发。Proxy 需在 rmq-proxy.json 配置 `enableACL` 与 `enableAclRpcHookForClusterMode`,且开启前应预建内部主题 DefaultHeartBeatSyncerTopic
+- **同步发送与单向发送**:Producer.Publish/PublishDelay 在 gRPC 模式下直接经 Proxy 发送,延迟等级按 Broker 默认 messageDelayLevel 换算为投递时间戳;PublishOneway 在 gRPC 下改为异步模拟(立即返回合成 SendOK,失败仅记录日志),不再抛 NotSupportedException
+- **系统保留键**:发送时过滤 TAGS/KEYS/DELAY/TRAN_MSG/PGROUP,避免 Proxy 以 ILLEGAL_MESSAGE_PROPERTY_KEY 拒绝
+- **GrpcPushConsumer 凭据**:新增 AccessKey/SecretKey,Proxy 启用 ACL 时可直接传入
+- **管理操作防护**:gRPC 模式下 9 个管理方法(建/删主题、订阅组、消息查询等)改为抛出带指引的 NotSupportedException,此前会因本地 Broker 列表为空而抛空引用异常
+- **优雅下线**:Stop 时主动调用 notifyClientTermination 告知 Proxy。此前只能等会话超时,窗口期内 Proxy 仍会把消息分配给已停止的消费者;实测通知后 Proxy 立即注销客户端并移除 channel,Stop 开销约 11ms
+- **本地环境**:Broker 启动加 -XX:MaxDirectMemorySize=1g 避免 POP 直接内存耗尽导致重试停滞;启动脚本与 CI 自动创建 Proxy 内部主题 DefaultHeartBeatSyncerTopic
+
+### 健壮性修复
+- **[fix]** 修复大消息解压:ZLIB 解压上限由固定 4MB 调整为默认 64MB 且可按实例配置,6MB 消息不再被解压上限误杀;解压超限不再被「ZLIB 头误判」退化路径吞掉而返回残缺数据
+- **[fix]** 修复解码失败导致队列假死:单条消息解码失败按 StoreSize 跳过后继续解析同批其余消息,不再丢弃整批;Consumer 新增 DecodeError 事件上报原始字节,整批不可解码时推进位点避免无限重拉(#120)
+- **[fix]** 修复轨迹分发器启动时机:延迟到名称服务器解析完成后再启动,避免阿里云场景启动抛空地址异常;生产者/消费者停止时释放分发器并注销轨迹钩子,消除后台线程与独立 Producer 泄漏
+- **[fix]** 修复 5.4/raft Broker 下消费者未注册:心跳体改 camelCase、注册前先查询、按需轮换 Broker 地址(#118)
+- **[fix]** 修复轨迹生产者未继承宿主 CloudProvider(#117)
+- **广播消费**:本地 offset 读取不到时改为从服务器获取
+
+### 性能与测试
+- 单元测试按测试类并行、依赖真实 Broker 的用例统一串行,全量耗时由约 3 分钟降至约 1 分 35 秒;以条件轮询替代固定等待,默认关闭框架日志(`ROCKETMQ_TEST_VERBOSE=1` 恢复)
+- 本地 RocketMQ 测试环境降载:三个 JVM 日志默认 WARN、异步刷盘 5 秒、commitlog 64MB、线程池收紧,新增 `--no-proxy`/`--store-dir`/`--log-level` 参数
+- 新增 Android/iOS 移动端冒烟工程(验证主库在移动端可加载并调用核心 API)与 riscv64/s390x 指令集冒烟工程
+- 新增跨文化鲁棒性与全量词表运行期校验用例;长稳脚本增加多主题多消费者与资源采样:4 分钟 108 条、30 分钟 702 条均全确认零异常,长连接重建 405 次零异常、无泄漏
+- 新增 AOT/JIT 性能对照基准(Benchmark 工程 + AotSmoke --bench):AOT 吞吐约为 JIT 的 54%~67%,换取启动 47 ms 与自包含 10.03 MB
+
+### CI 与工程化
+- **发布流程**:tag 推送时同时发布 NuGet.org 与 GitHub Packages,并依据 ChangeLog 对应段落自动创建 GitHub Release 并附加 nupkg/snupkg;手工触发只发包。发布任务运行在 Ubuntu runner
+- **测试矩阵**:新增 win-x64 / linux-arm64 / 龙芯 LA64 单元测试 job(先预热再全量、归档 trx、支持手动触发);新增 AOT 多 RID 冒烟矩阵(含 musl 容器与边缘 RID 手动任务)
+- **质量门禁**:README 语言切换行、NuGet 包版 README、译文结构、本地化词表缺键均纳入 CI 校验
+- 解决方案迁移为 .slnx 新格式;程序集与 NuGet 元数据改为英文并补充双语包描述
+
+### 文档与多语言 README
+- README 提供 11 种语言全译版本,默认语言切换为英文,补齐事件总线、运行时多语言与测试覆盖章节
+- 新增 HTTP 桥接指南、冷启动排障、AOT 兼容性与词表维护说明;生态版图与团队介绍与 NewLife.Core 同步
+- 升级依赖至 NewLife.Core 12.0.2026.1024
+
+---
+
 ## v3.2.2026.0802 (2026-08-02)
 
 ### gRPC 协议增强与健壮性
@@ -24,37 +95,6 @@
 - 重构 GitHub Actions RocketMQ 配置生成与下载方式,增强可读性和可维护性
 - 新增竞品分析文档,重构需求/功能清单/架构三件套文档体系并统一格式
 
-### 依赖升级与 NativeAOT 支持
-- **NewLife.Core v12 测试版**:升级到 12.0.2026.1013-beta0732,适配 v12 消息栈(IMessageCodec/MessagePump)与 JSON 源生成要求;本次升级不涉及代码改动(五个目标编译零告警)
-- **NativeAOT**:net10.0 目标开启 IsAotCompatible,库内序列化改走源生成成员访问器与元数据根,去除反射路径
-- **AOT 冒烟**:新增 AotSmoke 控制台工程(26 用例:帧编解码/请求头/JSON/云厂商适配/双协议转换/端到端收发/gRPC 链路含死信转发与 FIFO 顺序消费),CI 增加 linux-x64 发布运行步骤
-- **发布基线与监控**:新增 scripts/AotBaseline.cs 采集发布体积、启动开销与 CPU 吞吐并支持阈值判定,CI 输出流水线摘要并归档 JSON;win-x64 基线:可执行文件 10.03 MB、启动 47 ms
-- **版本策略**:AssemblyVersion 由 `3.2.*` 通配符改为 `3.2.0.0`(通配符与确定性构建冲突,且程序集版本宜只在发布时递增,FileVersion/PackageVersion 仍用完整日期版本)
-- **AOT 冒烟扩面**:AotSmoke 增至 33 用例(新增 ZLIB 压缩往返与解压上限、LMQ 属性、ACL 签名算法、大消息压缩端到端);AOT 发布统一加 IL2026/IL3050/IL2104 告警阻断并关闭单告警聚合(实测可拦截 IL3050 回归)
-- **AOT 对象体登记**:新增公共 API `MqAot.RegisterBodyType<T>()`——实测消费方自定义类型(POCO)消息体在裁剪后会被静默序列化为 `{}`,登记后正常;老目标框架为空实现,多目标工程可共用启动代码
-- **包消费路径 AOT 验证**:新增 AotPackageSmoke 工程,以 PackageReference 消费打包产物(区别于工程引用),覆盖包资产与依赖声明、源生成序列化、压缩、ACL 签名与端到端压缩往返;CI 增加 pack + 本地源恢复 + 发布 + 运行步骤,win-x64 实测零 IL 告警、8 用例全通过
-
-### RocketMQ 5.x gRPC 链路与消费语义
-- **Proxy 链路打通**:修复明文 h2c 未强制 HTTP/2、发送缺 MessageId、Telemetry 一次性上报后被注销、缺 grpc-timeout、PushConsumer 缺客户端标识等缺陷;新增 GrpcTelemetrySession 资源上报长连接(周期重建自愈,暴露 ConnectCount/ErrorCount)
-- **消费重试**:失败消息由 Broker 写入 %RETRY%{group}_{topic} 并按 popFromRetryProbability 概率并回原主题的拉取响应,客户端只需消费原主题;不可见时间下限收敛为 10 秒
-- **死信处理**:新增 GrpcPushConsumer.MaxDeliveryAttempts(默认16)达限转 %DLQ%{group},以及 Consumer.ForwardToDeadLetterQueueViaGrpcAsync、GetGrpcDlqTopic 与死信重投工具 scripts/DlqTool.cs
-- **事务消息**:修正 EndTransaction 的 resolution/source 字段编号错位(此前回滚被当作提交处理),实测提交可见、回滚不可见
-- **FIFO 顺序消费**:新增 Message.MessageGroup 与 GrpcPushConsumer.Orderly,实测并发度 20 下仍严格按发送顺序消费
-- **主题类型**:CreateTopic 的 topicMessageType 改为写入 attributes 的 message.type,FIFO/事务主题可正常创建
-- **ACL 2.0 鉴权**:修正 gRPC 签名输出为十六进制(Proxy 侧先 hex→base64 再比对);实测无凭据、非管理员、错误密钥均被拒,管理员账户可正常收发。Proxy 需在 rmq-proxy.json 配置 `enableACL` 与 `enableAclRpcHookForClusterMode`,且开启前应预建内部主题 DefaultHeartBeatSyncerTopic(否则 Proxy 因无凭据建主题失败而启动不了)
-- **同步发送**:Producer.Publish/PublishDelay 在 gRPC 模式下直接经 Proxy 发送(此前会因本地队列选择抛异常),延迟等级按 Broker 默认 messageDelayLevel 换算为投递时间戳;PublishOneway 在 gRPC 下没有单向语义,改为抛出 NotSupportedException
-- **系统保留键**:发送时过滤 TAGS/KEYS/DELAY/TRAN_MSG/PGROUP,避免 Proxy 以 ILLEGAL_MESSAGE_PROPERTY_KEY 拒绝
-- **GrpcPushConsumer 凭据**:新增 AccessKey/SecretKey,Proxy 启用 ACL 时可直接传入
-- **管理操作防护**:gRPC 模式下 9 个管理方法(建/删主题、订阅组、消息查询等)改为抛出带指引的 NotSupportedException,此前会因本地 Broker 列表为空而抛空引用异常
-- **优雅下线**:Stop 时主动调用 notifyClientTermination 告知 Proxy。此前只能等会话超时,窗口期内 Proxy 仍会把消息分配给已停止的消费者;实测通知后 Proxy 立即注销客户端并移除 channel,Stop 开销约 11ms
-- **本地环境**:Broker 启动加 -XX:MaxDirectMemorySize=1g 避免 POP 直接内存耗尽导致重试停滞;启动脚本与 CI 自动创建 Proxy 内部主题 DefaultHeartBeatSyncerTopic
-
-### 测试与长稳
-- gRPC 集成用例增至 9 个(路由/发送/接收确认/不可见重投/死信转发/推送重投/并发批量转死信/事务提交回滚/FIFO 顺序)
-- 长稳脚本新增多主题多消费者与资源采样(句柄/线程/工作集/GC/长连接重建计数):4 分钟 108 条、30 分钟 702 条均全确认零异常,长连接重建 405 次零异常、无泄漏
-- GitHub Actions 增加测试前预热步骤(规避冷启动时序)与夜间长稳流水线(注入 Proxy 重启)
-- 新增 AOT/JIT 性能对照基准(Benchmark 工程 + AotSmoke --bench):AOT 吞吐约为 JIT 的 54%~67%,换取启动 47 ms 与自包含 10.03 MB
-
 ---
 
 ## v3.1.2026.0601 (2026-06-01)
Modified +4 -4
diff --git a/NewLife.RocketMQ/NewLife.RocketMQ.csproj b/NewLife.RocketMQ/NewLife.RocketMQ.csproj
index 55fa25e..907809c 100644
--- a/NewLife.RocketMQ/NewLife.RocketMQ.csproj
+++ b/NewLife.RocketMQ/NewLife.RocketMQ.csproj
@@ -5,7 +5,7 @@
     <Description>Enterprise-grade fully managed RocketMQ client with dual-protocol support for Remoting 4.x/5.x and gRPC 5.x Proxy. Zero external dependencies: no Java, gRPC or Protobuf runtime required. Unified adapters for Alibaba Cloud, Huawei Cloud, Tencent Cloud and Apache ACL, with consume retry, dead-letter queue, transactional messages, ordered consumption and Pop consumption. Proven in billion-scale production systems.</Description>
     <Company>新生命开发团队</Company>
     <Copyright>©2002-2026 新生命开发团队</Copyright>
-    <VersionPrefix>3.2</VersionPrefix>
+    <VersionPrefix>4.0</VersionPrefix>
     <VersionSuffix>$([System.DateTime]::Now.ToString(`yyyy.MMdd`))</VersionSuffix>
     <Version>$(VersionPrefix).$(VersionSuffix)</Version>
     <FileVersion>$(Version)</FileVersion>
@@ -36,8 +36,8 @@
     <PackageIcon>leaf.png</PackageIcon>
     <RepositoryUrl>https://github.com/NewLifeX/NewLife.RocketMQ</RepositoryUrl>
     <RepositoryType>git</RepositoryType>
-    <PackageTags>新生命团队;X组件;NewLife;RocketMQ;纯托管;零依赖;Remoting;gRPC;阿里云;华为云;腾讯云;消息队列;MQ;分布式;事务消息;延迟消息;顺序消息;死信队列;MessageQueue;Queuing;Cloud;AOT;dotnet;csharp;$(AssemblyName)</PackageTags>
-    <PackageReleaseNotes>新增 MessageConverter 双协议消息模型转换助手,支持 Remoting 与 gRPC 消息互转;优化 gRPC 协议解析健壮性与并发安全,修复枚举偏移与字段编号问题,提升 PushConsumer 稳定性;统一云厂商 Provider 适配并升级依赖;修复 WriteLog 空引用与 TOPIC_NOT_EXIST 日志场景;新增 17 个云厂商单元测试及 gRPC 健壮性测试;优化 GitHub Actions 流程与集成测试自动启动</PackageReleaseNotes>
+    <PackageTags>新生命团队;X组件;NewLife;RocketMQ;纯托管;零依赖;Remoting;gRPC;阿里云;华为云;腾讯云;消息队列;MQ;分布式;事务消息;延迟消息;顺序消息;死信队列;事件总线;EventBus;MessageQueue;Queuing;Cloud;AOT;Localization;dotnet;csharp;$(AssemblyName)</PackageTags>
+    <PackageReleaseNotes>主版本升级:依赖 NewLife.Core 12 核心网络库并适配其消息栈与运行时多语言,程序集版本提升到 4.0;新增事件总线 RocketMqEventBus&lt;T&gt; 与事件枢纽工厂,支持跨进程发布订阅;全部运行时消息改为英文源文并内置 31 种语言词表,按文化自动翻译;net10.0 开启 NativeAOT 兼容并新增 MqAot.RegisterBodyType 对象体登记 API;打通 RocketMQ 5.x gRPC Proxy 链路,覆盖消费重试、死信、事务、FIFO 与 ACL 2.0;修复大消息解压、解码失败导致队列假死与轨迹分发器泄漏;发布流程同时推送 NuGet.org 与 GitHub Packages,并依据 ChangeLog 自动创建 GitHub Release</PackageReleaseNotes>
     <PackageLicenseExpression>MIT</PackageLicenseExpression>
     <PublishRepositoryUrl>true</PublishRepositoryUrl>
     <EmbedUntrackedSources>true</EmbedUntrackedSources>
@@ -69,7 +69,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="NewLife.Core" Version="12.0.2026.1021-beta0321" />
+    <PackageReference Include="NewLife.Core" Version="12.0.2026.1024" />
   </ItemGroup>
 
 </Project>
Modified +41 -1
diff --git a/README.ar.md b/README.ar.md
index 318a1aa..c6da14c 100644
--- a/README.ar.md
+++ b/README.ar.md
@@ -35,6 +35,7 @@ NewLife.RocketMQ هو **عميل RocketMQ مؤسسي مُدار بالكامل**
 | **صفر اعتماديات خارجية** | مرمّز حقول Protobuf مدمج (مكتوب يدويًا على SpanWriter/SpanReader في NewLife.Core)، دون الحاجة إلى Java أو بيئة تشغيل gRPC |
 | **دعم سحابات متعددة** | واجهة `ICloudProvider` موحّدة مع محوّلات مدمجة لـ Alibaba Cloud وHuawei Cloud وTencent Cloud وApache ACL |
 | **جاهز للإنتاج** | ميزات مؤسسية كاملة: إعادة محاولة الاستهلاك، وقائمة الرسائل الميتة، ومراجعة المعاملات، والاستهلاك المرتّب، واستهلاك Pop وغير ذلك |
+| **ناقل الأحداث** | ناقل أحداث مدمج قائم على عقد `IEventBus` من Core: تُنشر الأحداث وتُشترك بين العمليات عبر Producer/Consumer، مع إعادة محاولة وإرسال تلقائي إلى قائمة الرسائل الميتة |
 | **أوسع تغطية للأُطر** | من .NET Framework 4.5+ حتى .NET 10؛ وميزات gRPC متاحة على .NET Standard 2.1+ |
 | **ملائم لـ AOT** | هدف `net10.0` يدعم NativeAOT/trimming: ترميز الإطارات وفك ترميزها، وتسلسل JSON، وضغط الرسائل لا تعتمد على الانعكاس وقت التشغيل. يتضمّن المستودع اختبار دخان AOT واختبار دخان AOT لاستهلاك حزمة NuGet؛ ويتحقق CI من نشر AOT وتشغيله على مصفوفة RID رئيسية (win/linux/osx، وmusl، وLoongson LA64) |
 | **توطين وقت التشغيل** | السجلات، واستثناءات تحليل البروتوكول، واستثناءات واجهات API العامة، وأوصاف الإعدادات تستخدم الإنجليزية كنص مصدر، مع قوائم كلمات مدمجة لـ31 لغة تُترجَم تلقائيًا وفق `Localization.Culture` مع الرجوع إلى الإنجليزية؛ وتُترجَم السجلات ذات البادئة قبل تركيب البادئة، ولا تشارك البادئة في البحث داخل قائمة الكلمات |
@@ -54,7 +55,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ---
@@ -238,6 +239,36 @@ var msg = grpcMsg.ToMessage();      // Message (الحقول الأساسية)
 
 ---
 
+### ناقل الأحداث
+
+```csharp
+using NewLife.Messaging;
+using NewLife.RocketMQ;
+
+// يمكن أن تحتوي مواضيع الأحداث على نقاط؛ وتُطبَّع الأسماء إلى أسماء RocketMQ صالحة (order.created -> order_created)
+using var bus = new RocketMqEventBus<OrderPaidEvent>("127.0.0.1:9876", "order.created", "order_service");
+
+// الاشتراك: استثناء المعالج يؤدي إلى إعادة التسليم ثم إلى قائمة الرسائل الميتة
+await bus.SubscribeAsync((OrderPaidEvent e, IEventContext ctx) =>
+{
+    Console.WriteLine($"تم دفع الطلب: {e.OrderId}");
+    return Task.CompletedTask;
+}, "billing");
+
+// النشر: يُسلَّم عبر Broker، ويتلقاه المشتركون المحليون أيضًا عبر مجموعة المستهلكين
+await bus.PublishAsync(new OrderPaidEvent { OrderId = 1001 });
+
+// الربط بمركز أحداث: تُنشئ المصنع ناقلًا لكل موضوع وتخزّنه مؤقتًا
+var hub = new EventHub<OrderPaidEvent>
+{
+    Factory = new RocketMqEventBusFactory("127.0.0.1:9876"),
+};
+```
+
+> تستخدم مجموعة المستهلكين هوية العقدة الحالية افتراضيًا، بحيث تتلقى كل عقدة كل حدث. مرّر نفس clientId للتحويل إلى دلالة المستهلكين المتنافسين. حافظ على كون المعالجات idempotent لأن فشل جزء من الدفعة يعيد تسليم الدفعة كاملة.
+
+---
+
 ## ميزات المستهلك المتقدمة
 
 ### إعادة محاولة الاستهلاك وقائمة الرسائل الميتة
@@ -470,6 +501,15 @@ Cloud provider adapter layer
 | استهلاك Pop | ✅ | Pop/Ack/BatchAck/ChangeInvisibleTime |
 | خفض معدّل الاستهلاك | ✅ | تحكم بإشارة MaxConcurrentConsume |
 
+### ناقل الأحداث
+
+| الميزة | الحالة | الوصف |
+|------|:----:|------|
+| عقد Core IEventBus | ✅ | RocketMqEventBus&lt;TEvent&gt; / RocketMqEventContext |
+| نشر/اشتراك بين العمليات | ✅ | ينشر Producer، وتشترك مجموعة مستهلكي Consumer؛ وتُوجَّه الإخفاقات إلى إعادة المحاولة/قائمة الرسائل الميتة |
+| مصنع مركز الأحداث | ✅ | يطبّق RocketMqEventBusFactory واجهة IEventBusFactory ويُربط بـ EventHub.Factory |
+| تطبيع الأسماء | ✅ | MqEventBusNaming: تحويل الأحرف غير الصالحة إلى شرطات سفلية وقصّ إلى 127 حرفًا |
+
 ### الإدارة والعمليات
 
 | الميزة | الحالة | الوصف |
Modified +41 -1
diff --git a/README.de.md b/README.de.md
index 6a26020..d17db9e 100644
--- a/README.de.md
+++ b/README.de.md
@@ -35,6 +35,7 @@ NewLife.RocketMQ ist ein **vollständig verwalteter RocketMQ-Client in Enterpris
 | **Keine externen Abhängigkeiten** | Eingebauter Protobuf-Feld-Codec (handgeschrieben auf SpanWriter/SpanReader von NewLife.Core), keine Java- oder gRPC-Laufzeit erforderlich |
 | **Multi-Cloud-Unterstützung** | Einheitliche `ICloudProvider`-Schnittstelle mit eingebauten Adaptern für Alibaba Cloud, Huawei Cloud, Tencent Cloud und Apache ACL |
 | **Produktionsreif** | Vollständige Enterprise-Funktionen: Consume-Retry, Dead-Letter-Queue, Transaktions-Checkback, geordnete Verarbeitung, Pop-Consumption und mehr |
+| **Event-Bus** | Eingebauter Event-Bus auf Basis des Core-Vertrags `IEventBus`: Ereignisse werden über Producer/Consumer prozessübergreifend veröffentlicht und abonniert, mit automatischem Retry und Dead-Letter-Behandlung |
 | **Breiteste Framework-Abdeckung** | Von .NET Framework 4.5+ bis .NET 10; gRPC-Funktionen sind ab .NET Standard 2.1+ verfügbar |
 | **AOT-freundlich** | Das Ziel net10.0 unterstützt NativeAOT/Trimming: Frame-Codierung/-Decodierung, JSON-Serialisierung und Nachrichtenkomprimierung benötigen keine Laufzeitreflexion. Das Repository enthält einen AOT-Smoke-Test sowie einen AOT-Smoke-Test für die Nutzung des NuGet-Pakets; CI validiert AOT-Publishing und -Ausführung auf einer RID-Matrix gängiger Plattformen (win/linux/osx, musl und Loongson LA64) |
 | **Laufzeit-Lokalisierung** | Logs, Ausnahmen der Protokollanalyse, Ausnahmen öffentlicher APIs und Konfigurationsbeschreibungen verwenden Englisch als Quelltext, mit eingebauten Wortlisten für 31 Sprachen, automatisch übersetzt gemäß `Localization.Culture` mit englischem Fallback; Logs mit Präfix werden vor dem Anhängen des Präfixes übersetzt, und das Präfix nimmt nicht an der Wortlistensuche teil |
@@ -54,7 +55,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ---
@@ -238,6 +239,36 @@ var msg = grpcMsg.ToMessage();      // Message (Basisfelder)
 
 ---
 
+### Event-Bus
+
+```csharp
+using NewLife.Messaging;
+using NewLife.RocketMQ;
+
+// Ereignis-Topics dürfen Punkte enthalten; Namen werden auf gültige RocketMQ-Namen normalisiert (order.created -> order_created)
+using var bus = new RocketMqEventBus<OrderPaidEvent>("127.0.0.1:9876", "order.created", "order_service");
+
+// Abonnieren: Wirft der Handler eine Ausnahme, wird die Nachricht erneut zugestellt und landet schließlich in der Dead-Letter-Queue
+await bus.SubscribeAsync((OrderPaidEvent e, IEventContext ctx) =>
+{
+    Console.WriteLine($"Bestellung bezahlt: {e.OrderId}");
+    return Task.CompletedTask;
+}, "billing");
+
+// Veröffentlichen: Zustellung über den Broker; lokale Abonnenten erhalten sie ebenfalls über ihre Consumergruppe
+await bus.PublishAsync(new OrderPaidEvent { OrderId = 1001 });
+
+// An einen Event-Hub anbinden: Die Factory erstellt und cached einen Bus pro Topic
+var hub = new EventHub<OrderPaidEvent>
+{
+    Factory = new RocketMqEventBusFactory("127.0.0.1:9876"),
+};
+```
+
+> Die Consumergruppe verwendet standardmäßig die Identität des aktuellen Knotens, sodass jeder Knoten jedes Ereignis erhält. Übergib dieselbe clientId, um auf Competing-Consumer-Semantik umzuschalten. Halte Handler idempotent, da ein teilweiser Batch-Fehler den gesamten Batch erneut zustellt.
+
+---
+
 ## Erweiterte Consumer-Funktionen
 
 ### Consume-Retry und Dead-Letter-Queue
@@ -470,6 +501,15 @@ Siehe [Anforderungsdokument](Doc/需求文档.md), [Funktionsliste](Doc/功能
 | Pop-Consumption | ✅ | Pop/Ack/BatchAck/ChangeInvisibleTime |
 | Consume-Drosselung | ✅ | Semaphorsteuerung über MaxConcurrentConsume |
 
+### Event-Bus
+
+| Funktion | Status | Beschreibung |
+|---------|:------:|-------------|
+| Core-IEventBus-Vertrag | ✅ | RocketMqEventBus&lt;TEvent&gt; / RocketMqEventContext |
+| Prozessübergreifendes Pub/Sub | ✅ | Producer veröffentlicht, die Consumergruppe des Consumer abonniert; Fehler gehen in Retry/Dead-Letter |
+| Event-Hub-Factory | ✅ | RocketMqEventBusFactory implementiert IEventBusFactory und lässt sich an EventHub.Factory anbinden |
+| Namensnormalisierung | ✅ | MqEventBusNaming: ungültige Zeichen zu Unterstrichen, Kürzung auf 127 Zeichen |
+
 ### Verwaltung und Betrieb
 
 | Funktion | Status | Beschreibung |
Modified +41 -1
diff --git a/README.es.md b/README.es.md
index 40f6de2..9bf66ef 100644
--- a/README.es.md
+++ b/README.es.md
@@ -35,6 +35,7 @@ NewLife.RocketMQ es un **cliente RocketMQ empresarial, totalmente administrado**
 | **Sin dependencias externas** | Códec de campos Protobuf integrado (escrito a mano sobre SpanWriter/SpanReader de NewLife.Core), sin necesidad de runtime de Java ni de gRPC |
 | **Soporte multicloud** | Interfaz unificada `ICloudProvider` con adaptadores integrados para Alibaba Cloud, Huawei Cloud, Tencent Cloud y Apache ACL |
 | **Listo para producción** | Funciones empresariales completas: reintento de consumo, cola de mensajes muertos, verificación de transacciones, consumo ordenado, consumo Pop y más |
+| **Bus de eventos** | Bus de eventos integrado basado en el contrato `IEventBus` de Core: los eventos se publican y suscriben entre procesos mediante Producer/Consumer, con reintento y envío a la cola de mensajes muertos automáticos |
 | **Máxima cobertura de frameworks** | Desde .NET Framework 4.5+ hasta .NET 10; las funciones gRPC están disponibles en .NET Standard 2.1+ |
 | **Compatible con AOT** | El destino net10.0 admite NativeAOT/recorte: la codificación y decodificación de tramas, la serialización JSON y la compresión de mensajes no dependen de reflexión en tiempo de ejecución. El repositorio incluye una prueba de humo AOT y una prueba de humo AOT de consumo del paquete NuGet; la CI valida la publicación y ejecución AOT en una matriz de RID principales (win/linux/osx, musl y Loongson LA64) |
 | **Localización en tiempo de ejecución** | Los logs, las excepciones de análisis de protocolo, las excepciones de API pública y las descripciones de configuración usan el inglés como texto de origen, con listas de palabras integradas para 31 idiomas, traducidas automáticamente según `Localization.Culture` con retroceso al inglés; los logs con prefijo se traducen antes de componer el prefijo, y el prefijo no participa en la búsqueda en la lista de palabras |
@@ -54,7 +55,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ---
@@ -238,6 +239,36 @@ var msg = grpcMsg.ToMessage();      // Message (campos básicos)
 
 ---
 
+### Bus de eventos
+
+```csharp
+using NewLife.Messaging;
+using NewLife.RocketMQ;
+
+// Los topics de eventos pueden contener puntos; los nombres se normalizan a nombres válidos de RocketMQ (order.created -> order_created)
+using var bus = new RocketMqEventBus<OrderPaidEvent>("127.0.0.1:9876", "order.created", "order_service");
+
+// Suscripción: si el manejador lanza una excepción se reintenta la entrega y, al agotarse los intentos, el mensaje pasa a la cola de mensajes muertos
+await bus.SubscribeAsync((OrderPaidEvent e, IEventContext ctx) =>
+{
+    Console.WriteLine($"Pedido pagado: {e.OrderId}");
+    return Task.CompletedTask;
+}, "billing");
+
+// Publicación: se entrega a través del Broker; los suscriptores locales también la reciben mediante su grupo de consumidores
+await bus.PublishAsync(new OrderPaidEvent { OrderId = 1001 });
+
+// Integración con un hub de eventos: la fábrica crea y cachea un bus por topic
+var hub = new EventHub<OrderPaidEvent>
+{
+    Factory = new RocketMqEventBusFactory("127.0.0.1:9876"),
+};
+```
+
+> El grupo de consumidores toma por defecto la identidad del nodo actual, de modo que cada nodo recibe todos los eventos. Pasa el mismo clientId para cambiar a la semántica de consumidores competidores. Mantén los manejadores idempotentes, porque un fallo parcial de lote reentrega el lote completo.
+
+---
+
 ## Funciones avanzadas del consumidor
 
 ### Reintento de consumo y cola de mensajes muertos
@@ -470,6 +501,15 @@ Consulte el [documento de requisitos](Doc/需求文档.md), la [lista de funcion
 | Consumo Pop | ✅ | Pop/Ack/BatchAck/ChangeInvisibleTime |
 | Limitación del consumo | ✅ | Control por semáforo MaxConcurrentConsume |
 
+### Bus de eventos
+
+| Función | Estado | Descripción |
+|---------|:------:|-------------|
+| Contrato Core IEventBus | ✅ | RocketMqEventBus&lt;TEvent&gt; / RocketMqEventContext |
+| Publicación/suscripción entre procesos | ✅ | Producer publica, el grupo de consumidores de Consumer se suscribe; los fallos van a reintento/cola de mensajes muertos |
+| Fábrica de hub de eventos | ✅ | RocketMqEventBusFactory implementa IEventBusFactory y se conecta a EventHub.Factory |
+| Normalización de nombres | ✅ | MqEventBusNaming: caracteres no válidos a guiones bajos, truncado a 127 caracteres |
+
 ### Gestión y operación
 
 | Función | Estado | Descripción |
Modified +41 -1
diff --git a/README.fr.md b/README.fr.md
index d0e9154..8ebe0f5 100644
--- a/README.fr.md
+++ b/README.fr.md
@@ -35,6 +35,7 @@ NewLife.RocketMQ est un **client RocketMQ de qualité entreprise, entièrement m
 | **Aucune dépendance externe** | Codec de champs Protobuf intégré (écrit à la main sur SpanWriter/SpanReader de NewLife.Core), aucune runtime Java ou gRPC requise |
 | **Multi-cloud** | Interface unifiée `ICloudProvider` avec adaptateurs intégrés pour Alibaba Cloud, Huawei Cloud, Tencent Cloud et Apache ACL |
 | **Prêt pour la production** | Fonctionnalités d'entreprise complètes : reprise de consommation, file de messages morts, vérification des transactions, consommation ordonnée, consommation Pop, etc. |
+| **Bus d'événements** | Bus d'événements intégré basé sur le contrat `IEventBus` de Core : les événements sont publiés et souscrits entre processus via Producer/Consumer, avec reprise et file de messages morts automatiques |
 | **Couverture de frameworks la plus large** | De .NET Framework 4.5+ à .NET 10 ; les fonctionnalités gRPC sont disponibles à partir de .NET Standard 2.1+ |
 | **Compatible AOT** | La cible net10.0 prend en charge NativeAOT/trimming : l'encodage/décodage des trames, la sérialisation JSON et la compression des messages ne reposent pas sur la réflexion d'exécution. Le dépôt contient un smoke test AOT ainsi qu'un smoke test AOT de consommation du paquet NuGet ; la CI valide la publication et l'exécution AOT sur une matrice de RID courants (win/linux/osx, musl et Loongson LA64) |
 | **Localisation à l'exécution** | Les journaux, les exceptions d'analyse de protocole, les exceptions des API publiques et les descriptions de configuration utilisent l'anglais comme texte source, avec des listes de mots intégrées pour 31 langues, traduites automatiquement selon `Localization.Culture` avec repli sur l'anglais ; les journaux préfixés sont traduits avant la composition du préfixe, et le préfixe ne participe pas à la recherche dans la liste de mots |
@@ -54,7 +55,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ---
@@ -238,6 +239,36 @@ var msg = grpcMsg.ToMessage();      // Message (champs de base)
 
 ---
 
+### Bus d'événements
+
+```csharp
+using NewLife.Messaging;
+using NewLife.RocketMQ;
+
+// Les topics d'événements peuvent contenir des points ; les noms sont normalisés en noms RocketMQ valides (order.created -> order_created)
+using var bus = new RocketMqEventBus<OrderPaidEvent>("127.0.0.1:9876", "order.created", "order_service");
+
+// Abonnement : une exception du gestionnaire déclenche une nouvelle livraison, puis la file de messages morts
+await bus.SubscribeAsync((OrderPaidEvent e, IEventContext ctx) =>
+{
+    Console.WriteLine($"Commande payée : {e.OrderId}");
+    return Task.CompletedTask;
+}, "billing");
+
+// Publication : livrée via le Broker ; les abonnés locaux la reçoivent aussi via leur groupe de consommateurs
+await bus.PublishAsync(new OrderPaidEvent { OrderId = 1001 });
+
+// Branchement sur un hub d'événements : la fabrique crée et met en cache un bus par topic
+var hub = new EventHub<OrderPaidEvent>
+{
+    Factory = new RocketMqEventBusFactory("127.0.0.1:9876"),
+};
+```
+
+> Le groupe de consommateurs utilise par défaut l'identité du nœud courant, afin que chaque nœud reçoive chaque événement. Passez le même clientId pour passer à une sémantique de consommateurs concurrents. Gardez les gestionnaires idempotents, car l'échec partiel d'un lot entraîne la relivraison du lot complet.
+
+---
+
 ## Fonctionnalités avancées du Consumer
 
 ### Reprise de consommation et file de messages morts
@@ -470,6 +501,15 @@ Voir le [document de besoins](Doc/需求文档.md), la [liste des fonctionnalit
 | Consommation Pop | ✅ | Pop/Ack/BatchAck/ChangeInvisibleTime |
 | Limitation de consommation | ✅ | Contrôle par sémaphore MaxConcurrentConsume |
 
+### Bus d'événements
+
+| Fonctionnalité | État | Description |
+|---------|:------:|-------------|
+| Contrat Core IEventBus | ✅ | RocketMqEventBus&lt;TEvent&gt; / RocketMqEventContext |
+| Publication/abonnement inter-processus | ✅ | Producer publie, le groupe de consommateurs de Consumer s'abonne ; les échecs vont en reprise/file de messages morts |
+| Fabrique de hub d'événements | ✅ | RocketMqEventBusFactory implémente IEventBusFactory et se branche sur EventHub.Factory |
+| Normalisation des noms | ✅ | MqEventBusNaming : caractères invalides en soulignés, troncature à 127 caractères |
+
 ### Gestion et exploitation
 
 | Fonctionnalité | État | Description |
Modified +41 -1
diff --git a/README.ja.md b/README.ja.md
index afc09e6..803290c 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -35,6 +35,7 @@ NewLife.RocketMQ は、NewLife チームが .NET エコシステム向けに開
 | **外部依存ゼロ** | Protobuf フィールドコーデックを内蔵(NewLife.Core の SpanWriter/SpanReader 上に手書き実装)。Java や gRPC ランタイムは不要。 |
 | **マルチクラウド対応** | 統一インターフェース `ICloudProvider` と、Alibaba Cloud、Huawei Cloud、Tencent Cloud、Apache ACL のアダプターを内蔵。 |
 | **本番運用対応** | コンシュームリトライ、デッドレターキュー、トランザクションコールバック確認、順序消費、Pop 消費などのエンタープライズ機能を完備。 |
+| **イベントバス** | Core の `IEventBus` 契約に基づくイベントバスを内蔵:Producer/Consumer を介してプロセス間でイベントを発行・購読し、失敗時は自動でリトライ/デッドレター処理 |
 | **幅広いフレームワーク対応** | .NET Framework 4.5+ から .NET 10 まで。gRPC 機能は .NET Standard 2.1+ で利用可能。 |
 | **AOT フレンドリー** | net10.0 ターゲットは NativeAOT/トリミングに対応:フレームのエンコード/デコード、JSON シリアル化、メッセージ圧縮は実行時リフレクションに依存しません。リポジトリには AOT スモークテストと NuGet パッケージ消費側の AOT スモークテストを含み、CI は主要 RID マトリクス(win/linux/osx、musl、Loongson LA64)で AOT 公開と実行を検証します |
 | **実行時ローカライズ** | ログ、プロトコル解析例外、公開 API 例外、構成の説明は英語を原文とし、31 言語の単語リストを内蔵。`Localization.Culture` に従って自動翻訳し、英語にフォールバックします。接頭辞付きログは接頭辞を組み立てる前に翻訳され、接頭辞は単語リストの検索対象になりません |
@@ -54,7 +55,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ---
@@ -238,6 +239,36 @@ var msg = grpcMsg.ToMessage();      // Message(基本フィールド)
 
 ---
 
+### イベントバス
+
+```csharp
+using NewLife.Messaging;
+using NewLife.RocketMQ;
+
+// イベントトピックにはドットを含められます。名前は RocketMQ の有効な名前に正規化されます(order.created -> order_created)
+using var bus = new RocketMqEventBus<OrderPaidEvent>("127.0.0.1:9876", "order.created", "order_service");
+
+// 購読:ハンドラーが例外を投げると再配信され、上限を超えるとデッドレターキューに入ります
+await bus.SubscribeAsync((OrderPaidEvent e, IEventContext ctx) =>
+{
+    Console.WriteLine($"注文支払い完了: {e.OrderId}");
+    return Task.CompletedTask;
+}, "billing");
+
+// 発行:Broker 経由で配信され、ローカルの購読者もコンシューマーグループ経由で受け取ります
+await bus.PublishAsync(new OrderPaidEvent { OrderId = 1001 });
+
+// イベントハブへの接続:ファクトリがトピックごとにバスを作成してキャッシュします
+var hub = new EventHub<OrderPaidEvent>
+{
+    Factory = new RocketMqEventBusFactory("127.0.0.1:9876"),
+};
+```
+
+> コンシューマーグループは既定で現在のノード識別子を使用するため、各ノードがすべてのイベントを受信します。「グループ全体で 1 回だけ処理」したい場合は、同じ clientId を渡して競合コンシューマーのセマンティクスに切り替えてください。バッチの一部が失敗するとバッチ全体が再配信されるため、ハンドラーは冪等に保つ必要があります。
+
+---
+
 ## Consumer の高度な機能
 
 ### コンシュームリトライとデッドレターキュー
@@ -470,6 +501,15 @@ MqBase(業務基底クラス)
 | Pop 消費 | ✅ | Pop/Ack/BatchAck/ChangeInvisibleTime |
 | 消費スロットリング | ✅ | MaxConcurrentConsume によるセマフォ制御 |
 
+### イベントバス
+
+| 機能 | 状態 | 説明 |
+|------|:----:|------|
+| Core IEventBus 契約 | ✅ | RocketMqEventBus&lt;TEvent&gt; / RocketMqEventContext |
+| プロセス間 Pub/Sub | ✅ | Producer が発行し、Consumer のコンシューマーグループが購読。失敗はリトライ/デッドレターへ |
+| イベントハブファクトリ | ✅ | RocketMqEventBusFactory が IEventBusFactory を実装し、EventHub.Factory に接続可能 |
+| 名前の正規化 | ✅ | MqEventBusNaming:不正文字をアンダースコアに変換し、127 文字で切り捨て |
+
 ### 管理と運用
 
 | 機能 | 状態 | 説明 |
Modified +41 -1
diff --git a/README.ko.md b/README.ko.md
index aa96645..f8dda8f 100644
--- a/README.ko.md
+++ b/README.ko.md
@@ -35,6 +35,7 @@ NewLife.RocketMQ는 뉴라이프 팀이 .NET 생태계를 위해 개발한 **엔
 | **외부 의존성 제로** | 내장 Protobuf 필드 코덱(NewLife.Core의 SpanWriter/SpanReader 위에 직접 구현), Java나 gRPC 런타임 불필요 |
 | **멀티 클라우드 지원** | 통일된 `ICloudProvider` 인터페이스와 알리바바 클라우드·화웨이 클라우드·텐센트 클라우드·Apache ACL 내장 어댑터 |
 | **프로덕션 레디** | 소비 재시도, 데드 레터 큐, 트랜잭션 검사백, 순서 소비, Pop 소비 등 완전한 엔터프라이즈 기능 |
+| **이벤트 버스** | Core `IEventBus` 계약 기반의 내장 이벤트 버스: Producer/Consumer를 통해 프로세스 간에 이벤트를 발행·구독하며, 실패 시 자동 재시도/데드 레터 처리 |
 | **폭넓은 프레임워크 지원** | .NET Framework 4.5+부터 .NET 10까지; gRPC 기능은 .NET Standard 2.1+에서 사용 가능 |
 | **AOT 친화** | net10.0 타깃은 NativeAOT/트리밍을 지원: 프레임 인코딩/디코딩, JSON 직렬화, 메시지 압축이 런타임 리플렉션에 의존하지 않음. 저장소에 AOT 스모크 테스트와 NuGet 패키지 소비 AOT 스모크 테스트가 포함되며, CI가 주요 RID 매트릭스(win/linux/osx, musl 및 Loongson LA64)에서 AOT 게시와 실행을 검증 |
 | **런타임 현지화** | 로그, 프로토콜 파싱 예외, 공개 API 예외, 구성 설명이 영어를 원문으로 하며, 31개 언어 내장 단어 목록을 통해 `Localization.Culture`에 따라 자동 번역되고 영어로 폴백; 접두사가 붙은 로그는 접두사 조합 전에 번역되며 접두사는 단어 목록 조회에 참여하지 않음 |
@@ -54,7 +55,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ---
@@ -238,6 +239,36 @@ var msg = grpcMsg.ToMessage();      // Message (기본 필드)
 
 ---
 
+### 이벤트 버스
+
+```csharp
+using NewLife.Messaging;
+using NewLife.RocketMQ;
+
+// 이벤트 토픽에는 점을 포함할 수 있으며, 이름은 RocketMQ 유효 이름으로 정규화됩니다(order.created -> order_created)
+using var bus = new RocketMqEventBus<OrderPaidEvent>("127.0.0.1:9876", "order.created", "order_service");
+
+// 구독: 처리기가 예외를 던지면 재전송되고, 한도를 넘으면 데드 레터 큐로 이동합니다
+await bus.SubscribeAsync((OrderPaidEvent e, IEventContext ctx) =>
+{
+    Console.WriteLine($"주문 결제 완료: {e.OrderId}");
+    return Task.CompletedTask;
+}, "billing");
+
+// 발행: Broker를 통해 전달되며, 로컬 구독자도 소비자 그룹을 통해 수신합니다
+await bus.PublishAsync(new OrderPaidEvent { OrderId = 1001 });
+
+// 이벤트 허브 연결: 팩토리가 토픽별로 버스를 생성하고 캐시합니다
+var hub = new EventHub<OrderPaidEvent>
+{
+    Factory = new RocketMqEventBusFactory("127.0.0.1:9876"),
+};
+```
+
+> 소비자 그룹은 기본적으로 현재 노드 식별자를 사용하므로 모든 노드가 각 이벤트를 받습니다. 동일한 clientId를 전달하면 경쟁 소비자 의미로 전환됩니다. 배치 일부가 실패하면 전체 배치가 재전송되므로 처리기는 멱등성을 유지해야 합니다.
+
+---
+
 ## Consumer 고급 기능
 
 ### 소비 재시도와 데드 레터 큐
@@ -470,6 +501,15 @@ MqBase (비즈니스 기본 클래스)
 | Pop 소비 | ✅ | Pop/Ack/BatchAck/ChangeInvisibleTime |
 | 소비 스로틀링 | ✅ | MaxConcurrentConsume 세마포어 제어 |
 
+### 이벤트 버스
+
+| 기능 | 상태 | 설명 |
+|------|:----:|------|
+| Core IEventBus 계약 | ✅ | RocketMqEventBus&lt;TEvent&gt; / RocketMqEventContext |
+| 프로세스 간 게시/구독 | ✅ | Producer가 발행하고 Consumer 소비자 그룹이 구독; 실패는 재시도/데드 레터로 |
+| 이벤트 허브 팩토리 | ✅ | RocketMqEventBusFactory가 IEventBusFactory를 구현하며 EventHub.Factory에 연결 |
+| 이름 정규화 | ✅ | MqEventBusNaming: 잘못된 문자를 밑줄로, 127자 절단 |
+
 ### 관리 및 운영
 
 | 기능 | 상태 | 설명 |
Modified +1 -1
diff --git a/README.md b/README.md
index 0072a1e..c9dc030 100644
--- a/README.md
+++ b/README.md
@@ -53,7 +53,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ---
Modified +39 -1
diff --git a/README.nuget.md b/README.nuget.md
index 011cc5d..47186b5 100644
--- a/README.nuget.md
+++ b/README.nuget.md
@@ -35,6 +35,7 @@ NewLife.RocketMQ is an **enterprise-grade, fully managed RocketMQ client** devel
 | **Zero external dependencies** | Built-in Protobuf field codec (hand-written on NewLife.Core's SpanWriter/SpanReader), no Java or gRPC runtime required |
 | **Multi-cloud support** | Unified `ICloudProvider` interface with built-in adapters for Alibaba Cloud, Huawei Cloud, Tencent Cloud and Apache ACL |
 | **Production ready** | Complete enterprise features: consume retry, dead-letter queue, transaction checkback, ordered consumption, Pop consumption and more |
+| **Event bus** | Built-in event bus based on the Core `IEventBus` contract: events are published and subscribed across processes through Producer/Consumer, with automatic retry/dead-letter handling |
 | **Broadest framework coverage** | From .NET Framework 4.5+ to .NET 10; gRPC features are available on .NET Standard 2.1+ |
 | **AOT friendly** | The net10.0 target supports NativeAOT/trimming: frame encoding/decoding, JSON serialization and message compression do not rely on runtime reflection. The repository includes an AOT smoke test and a NuGet package consumption AOT smoke test; CI validates AOT publishing and execution on a mainstream RID matrix (win/linux/osx, musl and Loongson LA64) |
 | **Runtime localization** | Logs, protocol parsing exceptions, public API exceptions and configuration descriptions use English as the source text, with built-in word lists for 31 languages, translated automatically according to `Localization.Culture` with English fallback; prefixed logs are translated before the prefix is composed, and the prefix does not participate in word-list lookup |
@@ -54,7 +55,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ---
@@ -236,6 +237,34 @@ var ext = grpcMsg.ToMessageExt();   // MessageExt (includes all system propertie
 var msg = grpcMsg.ToMessage();      // Message (basic fields)
 ```
 
+### Event Bus
+
+```csharp
+using NewLife.Messaging;
+using NewLife.RocketMQ;
+
+// Event topics may contain dots; names are normalized to valid RocketMQ names (order.created -> order_created)
+using var bus = new RocketMqEventBus<OrderPaidEvent>("127.0.0.1:9876", "order.created", "order_service");
+
+// Subscribe: handler exceptions trigger redelivery, and messages eventually enter the dead-letter queue
+await bus.SubscribeAsync((OrderPaidEvent e, IEventContext ctx) =>
+{
+    Console.WriteLine($"Order paid: {e.OrderId}");
+    return Task.CompletedTask;
+}, "billing");
+
+// Publish: delivered through the Broker; local subscribers also receive it through their consumer group
+await bus.PublishAsync(new OrderPaidEvent { OrderId = 1001 });
+
+// Plug into an event hub: the factory creates and caches one bus per topic
+var hub = new EventHub<OrderPaidEvent>
+{
+    Factory = new RocketMqEventBusFactory("127.0.0.1:9876"),
+};
+```
+
+> The consumer group defaults to the current node identity so that every node receives each event. Pass the same clientId to switch to competing-consumer semantics. Keep handlers idempotent, because a partial batch failure redelivers the whole batch.
+
 ---
 
 ## Consumer Advanced Features
@@ -470,6 +499,15 @@ See the [Requirements Document](https://github.com/NewLifeX/NewLife.RocketMQ/blo
 | Pop consumption | ✅ | Pop/Ack/BatchAck/ChangeInvisibleTime |
 | Consume throttling | ✅ | MaxConcurrentConsume semaphore control |
 
+### Event Bus
+
+| Feature | Status | Description |
+|---------|:------:|-------------|
+| Core IEventBus contract | ✅ | RocketMqEventBus&lt;TEvent&gt; / RocketMqEventContext |
+| Cross-process pub/sub | ✅ | Producer publishes, Consumer consumer group subscribes, failures go to retry/dead-letter |
+| Event hub factory | ✅ | RocketMqEventBusFactory implements IEventBusFactory and plugs into EventHub.Factory |
+| Name normalization | ✅ | MqEventBusNaming: invalid characters to underscores, 127-character truncation |
+
 ### Management and Operations
 
 | Feature | Status | Description |
Modified +41 -1
diff --git a/README.pt.md b/README.pt.md
index 51368a1..37265ea 100644
--- a/README.pt.md
+++ b/README.pt.md
@@ -35,6 +35,7 @@ NewLife.RocketMQ é um **cliente RocketMQ empresarial totalmente gerenciado** de
 | **Zero dependências externas** | Codec de campos Protobuf embutido (escrito à mão sobre SpanWriter/SpanReader do NewLife.Core), sem exigir runtime Java ou gRPC |
 | **Suporte a múltiplas nuvens** | Interface unificada `ICloudProvider` com adaptadores embutidos para Alibaba Cloud, Huawei Cloud, Tencent Cloud e Apache ACL |
 | **Pronto para produção** | Recursos empresariais completos: nova tentativa de consumo, fila de mensagens mortas, verificação de transações, consumo ordenado, consumo Pop e mais |
+| **Barramento de eventos** | Barramento de eventos integrado baseado no contrato `IEventBus` do Core: os eventos são publicados e assinados entre processos por meio de Producer/Consumer, com nova tentativa e fila de mensagens mortas automáticas |
 | **Maior cobertura de frameworks** | Do .NET Framework 4.5+ ao .NET 10; os recursos gRPC estão disponíveis a partir do .NET Standard 2.1 |
 | **Compatível com AOT** | O alvo net10.0 suporta NativeAOT/trimming: codificação/decodificação de quadros, serialização JSON e compactação de mensagens não dependem de reflexão em tempo de execução. O repositório inclui um teste de fumaça AOT e um teste de fumaça AOT de consumo do pacote NuGet; a CI valida a publicação e a execução AOT em uma matriz de RIDs mainstream (win/linux/osx, musl e Loongson LA64) |
 | **Localização em tempo de execução** | Logs, exceções de análise de protocolo, exceções de API pública e descrições de configuração usam o inglês como texto de origem, com listas de palavras embutidas para 31 idiomas, traduzidas automaticamente conforme `Localization.Culture` com fallback para o inglês; logs com prefixo são traduzidos antes da composição do prefixo, e o prefixo não participa da busca na lista de palavras |
@@ -54,7 +55,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ---
@@ -238,6 +239,36 @@ var msg = grpcMsg.ToMessage();      // Message (campos básicos)
 
 ---
 
+### Barramento de eventos
+
+```csharp
+using NewLife.Messaging;
+using NewLife.RocketMQ;
+
+// Os tópicos de eventos podem conter pontos; os nomes são normalizados para nomes válidos do RocketMQ (order.created -> order_created)
+using var bus = new RocketMqEventBus<OrderPaidEvent>("127.0.0.1:9876", "order.created", "order_service");
+
+// Assinatura: exceções no manipulador disparam nova entrega e, ao esgotar as tentativas, a mensagem vai para a fila de mensagens mortas
+await bus.SubscribeAsync((OrderPaidEvent e, IEventContext ctx) =>
+{
+    Console.WriteLine($"Pedido pago: {e.OrderId}");
+    return Task.CompletedTask;
+}, "billing");
+
+// Publicação: entregue pelo Broker; assinantes locais também a recebem pelo seu grupo de consumidores
+await bus.PublishAsync(new OrderPaidEvent { OrderId = 1001 });
+
+// Integração com um hub de eventos: a fábrica cria e armazena em cache um barramento por tópico
+var hub = new EventHub<OrderPaidEvent>
+{
+    Factory = new RocketMqEventBusFactory("127.0.0.1:9876"),
+};
+```
+
+> O grupo de consumidores usa por padrão a identidade do nó atual, para que cada nó receba cada evento. Passe o mesmo clientId para mudar para a semântica de consumidores concorrentes. Mantenha os manipuladores idempotentes, pois a falha parcial de um lote reentrega o lote inteiro.
+
+---
+
 ## Recursos avançados do consumidor
 
 ### Nova tentativa de consumo e fila de mensagens mortas
@@ -470,6 +501,15 @@ Consulte o [Documento de requisitos](Doc/需求文档.md), a [Lista de funcional
 | Consumo Pop | ✅ | Pop/Ack/BatchAck/ChangeInvisibleTime |
 | Limitação de consumo | ✅ | Controle por semáforo MaxConcurrentConsume |
 
+### Barramento de eventos
+
+| Recurso | Status | Descrição |
+|---------|:------:|-------------|
+| Contrato IEventBus do Core | ✅ | RocketMqEventBus&lt;TEvent&gt; / RocketMqEventContext |
+| Pub/Sub entre processos | ✅ | Producer publica, o grupo de consumidores do Consumer assina; falhas vão para nova tentativa/fila de mensagens mortas |
+| Fábrica de hub de eventos | ✅ | RocketMqEventBusFactory implementa IEventBusFactory e se conecta a EventHub.Factory |
+| Normalização de nomes | ✅ | MqEventBusNaming: caracteres inválidos para sublinhado, truncamento em 127 caracteres |
+
 ### Gerenciamento e operações
 
 | Recurso | Status | Descrição |
Modified +41 -1
diff --git a/README.ru.md b/README.ru.md
index 8b8dd12..16cf67a 100644
--- a/README.ru.md
+++ b/README.ru.md
@@ -35,6 +35,7 @@ NewLife.RocketMQ — **корпоративный полностью управ
 | **Ноль внешних зависимостей** | Встроенный кодек полей Protobuf (написан вручную на SpanWriter/SpanReader из NewLife.Core), не требуется среда выполнения Java или gRPC |
 | **Поддержка нескольких облаков** | Единый интерфейс `ICloudProvider` со встроенными адаптерами для Alibaba Cloud, Huawei Cloud, Tencent Cloud и Apache ACL |
 | **Готовность к эксплуатации** | Полный набор корпоративных функций: повторное потребление, очередь недоставленных сообщений, проверка транзакций, упорядоченное потребление, Pop-потребление и многое другое |
+| **Шина событий** | Встроенная шина событий на основе контракта `IEventBus` из Core: события публикуются и подписываются между процессами через Producer/Consumer, с автоматическими повторами и очередью недоставленных сообщений |
 | **Самый широкий охват платформ** | От .NET Framework 4.5+ до .NET 10; функции gRPC доступны начиная с .NET Standard 2.1+ |
 | **Дружелюбность к AOT** | Целевая платформа net10.0 поддерживает NativeAOT/тримминг: кодирование и декодирование кадров, сериализация JSON и сжатие сообщений не зависят от рефлексии времени выполнения. В репозитории есть AOT smoke-тест и AOT smoke-тест потребления NuGet-пакета; CI проверяет публикацию и запуск AOT на матрице основных RID (win/linux/osx, musl и Loongson LA64) |
 | **Локализация во время выполнения** | Логи, исключения разбора протокола, исключения публичного API и описания конфигурации используют английский текст как исходный, со встроенными словарями для 31 языка; перевод выполняется автоматически в соответствии с `Localization.Culture` с откатом на английский; логи с префиксом переводятся до формирования префикса, и префикс не участвует в поиске по словарю |
@@ -54,7 +55,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ## Быстрый старт
@@ -236,6 +237,36 @@ var msg = grpcMsg.ToMessage();      // Message (базовые поля)
 
 ---
 
+### Шина событий
+
+```csharp
+using NewLife.Messaging;
+using NewLife.RocketMQ;
+
+// Топики событий могут содержать точки; имена нормализуются в допустимые имена RocketMQ (order.created -> order_created)
+using var bus = new RocketMqEventBus<OrderPaidEvent>("127.0.0.1:9876", "order.created", "order_service");
+
+// Подписка: исключение в обработчике вызывает повторную доставку, а затем сообщение попадает в очередь недоставленных
+await bus.SubscribeAsync((OrderPaidEvent e, IEventContext ctx) =>
+{
+    Console.WriteLine($"Заказ оплачен: {e.OrderId}");
+    return Task.CompletedTask;
+}, "billing");
+
+// Публикация: доставка через Broker; локальные подписчики также получают событие через свою группу потребителей
+await bus.PublishAsync(new OrderPaidEvent { OrderId = 1001 });
+
+// Подключение к хабу событий: фабрика создаёт и кэширует шину для каждого топика
+var hub = new EventHub<OrderPaidEvent>
+{
+    Factory = new RocketMqEventBusFactory("127.0.0.1:9876"),
+};
+```
+
+> Группа потребителей по умолчанию использует идентификатор текущего узла, поэтому каждый узел получает каждое событие. Передайте одинаковый clientId, чтобы перейти к семантике конкурирующих потребителей. Обработчики должны быть идемпотентными, так как частичный сбой пакета приводит к повторной доставке всего пакета.
+
+---
+
 ## Расширенные возможности потребителя
 
 ### Повторное потребление и очередь недоставленных сообщений
@@ -468,6 +499,15 @@ MqBase (базовый бизнес-класс)
 | Pop-потребление | ✅ | Pop/Ack/BatchAck/ChangeInvisibleTime |
 | Ограничение потребления | ✅ | Управление семафором MaxConcurrentConsume |
 
+### Шина событий
+
+| Возможность | Статус | Описание |
+|---------|:------:|-------------|
+| Контракт Core IEventBus | ✅ | RocketMqEventBus&lt;TEvent&gt; / RocketMqEventContext |
+| Межпроцессная публикация/подписка | ✅ | Producer публикует, группа потребителей Consumer подписывается; сбои уходят в повтор/очередь недоставленных |
+| Фабрика хаба событий | ✅ | RocketMqEventBusFactory реализует IEventBusFactory и подключается к EventHub.Factory |
+| Нормализация имён | ✅ | MqEventBusNaming: недопустимые символы в подчёркивания, обрезка до 127 символов |
+
 ### Управление и эксплуатация
 
 | Возможность | Статус | Описание |
Modified +1 -1
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 2ad0371..b1053a6 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -56,7 +56,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ---
Modified +41 -1
diff --git a/README.zh-TW.md b/README.zh-TW.md
index 0eb30cc..c498cdc 100644
--- a/README.zh-TW.md
+++ b/README.zh-TW.md
@@ -35,6 +35,7 @@ NewLife.RocketMQ 是新生命團隊開發的**企業級純受控 RocketMQ 用戶
 | **零外部相依** | 內建 Protobuf 欄位編解碼(基於 NewLife.Core 的 SpanWriter/SpanReader 手寫實作),無需 Java 或 gRPC 執行階段 |
 | **多雲適配** | 統一 `ICloudProvider` 介面,已內建阿里雲/華為雲/騰訊雲/Apache ACL 四家適配器 |
 | **生產就緒** | 消費重試、死信佇列、交易回查、順序消費、Pop 消費等企業級特性完整支援 |
+| **事件匯流排** | 內建基於 Core `IEventBus` 契約的事件匯流排:事件經 Producer/Consumer 跨行程發佈與訂閱,失敗自動回投重試/死信 |
 | **最廣框架涵蓋** | .NET Framework 4.5+ 到 .NET 10,gRPC 功能在 .NET Standard 2.1+ 可用 |
 | **AOT 友善** | net10.0 目標支援 NativeAOT/裁剪:訊框編解碼、JSON 序列化與訊息壓縮不依賴執行階段反射,儲存庫內建 AOT 冒煙與 NuGet 套件消費 AOT 冒煙;CI 以主流 RID 矩陣(win/linux/osx、musl 及龍芯 LA64)驗證 AOT 發佈與執行 |
 | **執行階段多語言** | 日誌、協定解析例外、公開 API 例外與設定項描述以英文為源文,內建 31 種語言詞表,按 `Localization.Culture` 自動翻譯並回退英文;帶前綴日誌先翻譯再拼前綴,前綴不參與詞表查找 |
@@ -54,7 +55,7 @@ dotnet add package NewLife.RocketMQ
 
 ```xml
 <!-- PackageReference -->
-<PackageReference Include="NewLife.RocketMQ" Version="3.0.*" />
+<PackageReference Include="NewLife.RocketMQ" Version="4.0.*" />
 ```
 
 ---
@@ -238,6 +239,36 @@ var msg = grpcMsg.ToMessage();      // Message(基礎欄位)
 
 ---
 
+### 事件匯流排(Event Bus)
+
+```csharp
+using NewLife.Messaging;
+using NewLife.RocketMQ;
+
+// 事件主題可直接使用 order.created,內部自動轉換為 RocketMQ 合法名稱 order_created
+using var bus = new RocketMqEventBus<OrderPaidEvent>("127.0.0.1:9876", "order.created", "order_service");
+
+// 訂閱:處理常式拋出例外時回投重試,超過上限進入死信佇列
+await bus.SubscribeAsync((OrderPaidEvent e, IEventContext ctx) =>
+{
+    Console.WriteLine($"收到付款成功事件:{e.OrderId}");
+    return Task.CompletedTask;
+}, "billing");
+
+// 發佈:經 Broker 投遞,本機訂閱者同樣透過消費組收到
+await bus.PublishAsync(new OrderPaidEvent { OrderId = 1001 });
+
+// 接入事件中樞:工廠按主題建立並快取匯流排
+var hub = new EventHub<OrderPaidEvent>
+{
+    Factory = new RocketMqEventBusFactory("127.0.0.1:9876"),
+};
+```
+
+> 消費組預設取本機識別,每個節點各成一組,因此每個節點都能收到事件;需要「整組只處理一次」時,向工廠傳入相同的 clientId。處理常式應保持冪等(同批次部分失敗會整批重投)。
+
+---
+
 ## 消費者進階特性
 
 ### 消費重試與死信佇列
@@ -470,6 +501,15 @@ MqBase (業務基底類別)
 | Pop 消費 | ✅ | Pop/Ack/BatchAck/ChangeInvisibleTime |
 | 消費限流 | ✅ | MaxConcurrentConsume 號誌控制 |
 
+### 事件匯流排
+
+| 功能 | 狀態 | 說明 |
+|------|:----:|------|
+| Core IEventBus 契約 | ✅ | RocketMqEventBus&lt;TEvent&gt; / RocketMqEventContext |
+| 跨行程發佈訂閱 | ✅ | Producer 發佈、Consumer 消費組訂閱,失敗回投重試/死信 |
+| 事件中樞工廠 | ✅ | RocketMqEventBusFactory 實作 IEventBusFactory,可掛 EventHub.Factory |
+| 名稱正規化 | ✅ | MqEventBusNaming,非法字元→底線、127 字元截斷 |
+
 ### 管理與維運
 
 | 功能 | 狀態 | 說明 |