Azure Service Bus主题订阅:如何为每个订阅者发送自定义消息内容
实现Azure Service Bus订阅的自定义消息格式需求
你需要给不同订阅发送不同字段的精简消息,Service Bus的过滤器确实只能决定是否转发整条消息,没法修改内容,这里给两个实用的解决方案:
方案一:发布时生成多份消息,配合过滤器路由
直接在发布消息的时候,针对每个订阅的需求构造对应的消息内容,然后给每条消息加一个自定义属性(比如TargetSubscription),再给每个订阅设置SQL过滤器匹配这个属性,让每个订阅只接收自己对应的消息。
代码示例(C#)
await using var client = new ServiceBusClient("你的连接字符串"); var sender = client.CreateSender("你的主题名称"); // 给sub1发完整消息 var fullMsg = new ServiceBusMessage(JsonSerializer.Serialize(new { A = "值1", B = "值2", C = "值3", D = "值4" })); fullMsg.ApplicationProperties["TargetSubscription"] = "sub1"; await sender.SendMessageAsync(fullMsg); // 给sub2发仅含A、B的消息 var sub2Msg = new ServiceBusMessage(JsonSerializer.Serialize(new { A = "值1", B = "值2" })); sub2Msg.ApplicationProperties["TargetSubscription"] = "sub2"; await sender.SendMessageAsync(sub2Msg); // 给sub3发含A、B、C的消息 var sub3Msg = new ServiceBusMessage(JsonSerializer.Serialize(new { A = "值1", B = "值2", C = "值3" })); sub3Msg.ApplicationProperties["TargetSubscription"] = "sub3"; await sender.SendMessageAsync(sub3Msg);
订阅过滤器设置
- 给sub1设置SQL过滤器:
TargetSubscription = 'sub1' - 给sub2设置SQL过滤器:
TargetSubscription = 'sub2' - 给sub3设置SQL过滤器:
TargetSubscription = 'sub3'
这个方案简单直接,不需要额外依赖,但发布端要多发送几条消息,适合订阅数量不多的场景。
方案二:用Azure Functions做中间转发层
如果不想修改发布端的代码,只需要发布一次完整消息,可以加一个Azure Functions作为中间层:监听主题的完整消息,然后根据每个订阅的需求构造精简版消息,再转发到对应的订阅。
代码示例(C# Azure Functions)
[FunctionName("MessageTransformer")] public static async Task Run( [ServiceBusTrigger("你的主题名称", Connection = "ServiceBusConnection")] ServiceBusReceivedMessage originalMsg, [ServiceBus("你的主题名称/subscriptions/sub2", Connection = "ServiceBusConnection")] IAsyncCollector<ServiceBusMessage> sub2Sender, [ServiceBus("你的主题名称/subscriptions/sub3", Connection = "ServiceBusConnection")] IAsyncCollector<ServiceBusMessage> sub3Sender, ILogger log) { // 解析原始完整消息 var originalData = JsonSerializer.Deserialize<OriginalMessage>(originalMsg.Body); // 构造并发送sub2需要的消息 var sub2Data = new { A = originalData.A, B = originalData.B }; await sub2Sender.AddAsync(new ServiceBusMessage(JsonSerializer.Serialize(sub2Data))); // 构造并发送sub3需要的消息 var sub3Data = new { A = originalData.A, B = originalData.B, C = originalData.C }; await sub3Sender.AddAsync(new ServiceBusMessage(JsonSerializer.Serialize(sub3Data))); // sub1直接订阅原主题,无需经过这个函数 } // 定义原始消息结构 public class OriginalMessage { public string A { get; set; } public string B { get; set; } public string C { get; set; } public string D { get; set; } }
这个方案的好处是发布端只需发一次消息,所有转换逻辑集中在函数里,后续调整字段只需要改函数代码,适合订阅数量多或者发布端无法修改的场景,但需要额外维护Azure Functions组件。
内容的提问来源于stack exchange,提问作者Erfan
相关产品推荐
相关产品推荐

