You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在收发两端通用拦截Azure Service Bus消息并无侵入式处理属性?

当然有办法实现这个需求!针对Azure Service Bus结合WCF的场景,IClientMessageInspector和IDispatchMessageInspector确实是完美的拦截器方案,不用修改原有收发业务代码就能实现通用的消息属性注入与读取。下面给你一个完整可运行的示例,涵盖从拦截器实现到配置启用的全流程:

一、实现客户端拦截器(发送时自动添加属性)

这个拦截器会在消息发送前,自动向消息中添加通用属性,比如发送时间、客户端标识之类的:

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;

public class ServiceBusClientInspector : IClientMessageInspector
{
    // 发送消息前拦截,添加自定义属性
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        // 添加自定义属性到消息Properties集合
        request.Properties["X-Client-Send-Time"] = DateTime.UtcNow.ToString("o");
        request.Properties["X-Client-Id"] = Environment.MachineName;
        
        return null;
    }

    // 接收响应后处理(这里我们不需要,留空即可)
    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
    }
}

// 行为扩展类,用于将拦截器添加到客户端行为中
public class ServiceBusClientBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        // 将自定义拦截器添加到客户端运行时
        clientRuntime.ClientMessageInspectors.Add(new ServiceBusClientInspector());
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
}
二、实现服务端拦截器(接收时自动读取属性)

服务端拦截器会在消息接收后,自动读取并处理这些通用属性,比如记录日志或者做业务校验:

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;

public class ServiceBusDispatchInspector : IDispatchMessageInspector
{
    // 接收消息后拦截,读取自定义属性
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        if (request.Properties.ContainsKey("X-Client-Send-Time"))
        {
            var sendTime = request.Properties["X-Client-Send-Time"].ToString();
            Console.WriteLine($"收到来自客户端的消息,发送时间:{sendTime}");
        }

        if (request.Properties.ContainsKey("X-Client-Id"))
        {
            var clientId = request.Properties["X-Client-Id"].ToString();
            Console.WriteLine($"客户端标识:{clientId}");
        }

        return null;
    }

    // 发送响应前处理(这里我们不需要,留空即可)
    public void BeforeSendReply(ref Message reply, object correlationState)
    {
    }
}

// 行为扩展类,用于将拦截器添加到服务端行为中
public class ServiceBusDispatchBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        // 将自定义拦截器添加到服务端调度运行时
        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new ServiceBusDispatchInspector());
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
}
三、配置WCF端点启用拦截器

你可以通过配置文件或者代码配置两种方式启用这些拦截器:

方式1:通过App.config/Web.config配置

首先要注册行为扩展,然后在端点行为中引用:

<system.serviceModel>
  <extensions>
    <behaviorExtensions>
      <!-- 注册客户端行为扩展 -->
      <add name="serviceBusClientBehavior" 
           type="YourNamespace.ServiceBusClientBehavior, YourAssemblyName"/>
      <!-- 注册服务端行为扩展 -->
      <add name="serviceBusDispatchBehavior" 
           type="YourNamespace.ServiceBusDispatchBehavior, YourAssemblyName"/>
    </behaviorExtensions>
  </extensions>

  <behaviors>
    <endpointBehaviors>
      <behavior name="ClientWithInterceptor">
        <serviceBusClientBehavior />
      </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
      <behavior name="ServiceWithInterceptor">
        <serviceMetadata httpGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="false"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>

  <!-- 客户端端点配置 -->
  <client>
    <endpoint address="sb://your-servicebus-namespace.servicebus.windows.net/your-queue"
              binding="netMessagingBinding"
              bindingConfiguration="NetMessagingBinding"
              contract="YourNamespace.IYourServiceContract"
              behaviorConfiguration="ClientWithInterceptor"/>
  </client>

  <!-- 服务端端点配置 -->
  <services>
    <service name="YourNamespace.YourServiceImplementation" behaviorConfiguration="ServiceWithInterceptor">
      <endpoint address="sb://your-servicebus-namespace.servicebus.windows.net/your-queue"
                binding="netMessagingBinding"
                bindingConfiguration="NetMessagingBinding"
                contract="YourNamespace.IYourServiceContract"
                behaviorConfiguration="ServiceWithInterceptorEndpoint"/>
    </service>
  </services>

  <bindings>
    <netMessagingBinding>
      <binding name="NetMessagingBinding">
        <transportSettings batchFlushInterval="00:00:01"/>
      </binding>
    </netMessagingBinding>
  </bindings>
</system.serviceModel>

方式2:通过代码动态配置

如果你的WCF客户端/服务是通过代码创建的,可以直接添加行为:

客户端代码配置示例:

var endpointAddress = new EndpointAddress("sb://your-servicebus-namespace.servicebus.windows.net/your-queue");
var binding = new NetMessagingBinding();

var factory = new ChannelFactory<IYourServiceContract>(binding, endpointAddress);
// 添加客户端拦截器行为
factory.Endpoint.Behaviors.Add(new ServiceBusClientBehavior());

var client = factory.CreateChannel();
// 此时调用服务方法,消息会自动带上自定义属性
client.YourServiceMethod();

服务端代码配置示例:

var serviceHost = new ServiceHost(typeof(YourServiceImplementation));
var endpoint = serviceHost.AddServiceEndpoint(
    typeof(IYourServiceContract),
    new NetMessagingBinding(),
    "sb://your-servicebus-namespace.servicebus.windows.net/your-queue");
// 添加服务端拦截器行为
endpoint.Behaviors.Add(new ServiceBusDispatchBehavior());

serviceHost.Open();
四、验证效果

当你运行客户端发送消息时,客户端拦截器会自动添加X-Client-Send-Time和X-Client-Id属性;服务端接收到消息后,拦截器会读取这些属性并打印到控制台(或者你可以改成记录到日志系统)。整个过程完全不需要修改原有业务的收发代码,实现了通用的属性处理逻辑。

内容的提问来源于stack exchange,提问作者Jörgen Sigvardsson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:10:59