在运行时停止/启动 WCF MEX 服务

2024-04-19

是否可以/如何在运行时停止和启动自托管 WCF 服务的 HTTP MEX 侦听器而不影响主 WCF 服务?

(请不要问我为什么要这样做。这是一种绕过别人人为限制的黑客行为。)


*****[在重新测试和代码清理后重新添加了这个答案]这是我添加到我的基于 WCF 的通用服务开发框架中的实际代码,并且它已经过全面测试。*****

假设您一开始就启用了 MEXServiceHost...

下面的解决方案被写入 的条款ServiceHost子类 (WCFServiceHost<T>)实现 一个特殊的接口(IWCFState) 为了 存储 MEX 的实例EndpointDispatcher class.

首先,添加这些命名空间...

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

其次,定义IWCFState界面...

public interface IWCFState
{
    EndpointDispatcher MexEndpointDispatcher
    {
        get;
        set;
    }
}

第三,为一些创建静态类ServiceHost扩展方法(我们将在下面填写)...

public static class WCFExtensions
{
    public static void RemoveMexEndpointDispatcher(this ServiceHost host){}

    public static void AddMexEndpointDispatcher(this ServiceHost host){}
}

现在让我们填写扩展方法...

停止 MEXServiceHost在运行时

public static void RemoveMexEndpointDispatcher(this ServiceHost host)
{
    // In the simple example, we only define one MEX endpoint for
    // one transport protocol
    var queryMexChannelDisps = 
            host.ChannelDispatchers.Where(
                disp => (((ChannelDispatcher)disp).Endpoints[0].ContractName
                                            == "IMetadataExchange"));
    var channelDisp = (ChannelDispatcher)queryMexChannelDisps.First();

    // Save the MEX EndpointDispatcher
    ((IWCFState)host).MexEndpointDispatcher = channelDisp.Endpoints[0];

    channelDisp.Endpoints.Remove(channelDisp.Endpoints[0]);
}

然后这样称呼它...

// WCFServiceHost<T> inherits from ServiceHost and T is the Service Type,
// with the new() condition for the generic type T.  It encapsulates 
// the creation of the Service Type that is passed into the base class 
// constructor.
Uri baseAddress = new Uri("someValidURI");
WCFServiceHost<T> serviceImplementation = new WCFServiceHost<T>(baseAddress);

// We must open the ServiceHost first...
serviceImplementation.Open();

// Let's turn MEX off by default.
serviceImplementation.RemoveMexEndpointDispatcher();

在 a 上(再次)启动 MEXServiceHost在运行时

public static void AddMexEndpointDispatcher(this ServiceHost host)
{
    var queryMexChannelDisps =
            host.ChannelDispatchers.Where(
                    disp => (((ChannelDispatcher)disp).Endpoints.Count == 0));
    var channelDisp = (ChannelDispatcher)queryMexChannelDisps.First();

    // Add the MEX EndpointDispatcher
    channelDisp.Endpoints.Add(((IWCFState)host).MexEndpointDispatcher);
}

然后这样称呼它...

serviceImplementation.AddMexEndpointDispatcher();

Summary

此设计允许您使用一些消息传递方法将命令发送到服务本身或托管服务的代码,并让它执行 MEX 的启用或禁用EndpointDispatcher,为此有效地关闭 MEXServiceHost.

注意:此设计假设代码在启动时支持 MEX,但随后它将使用配置设置来确定服务在调用后是否禁用 MEXOpen() on the ServiceHost。如果您尝试在之前调用任一扩展方法,则会抛出此代码ServiceHost已被打开。

注意事项:我可能会创建一个特殊的服务实例,其管理操作在启动时不支持 MEX,并将其建立为服务控制通道。

资源

在解决这个问题时,我发现以下两个资源不可或缺:

  • .NET 反射器:类浏览器、分析器和反编译器,用于检查 System.ServiceModel.dll 等程序集: http://www.red-gate.com/products/reflector/ http://www.red-gate.com/products/reflector/

  • 扩展调度程序 (MSDN):提供了 WCF 服务的类组成的精彩高级图表:http://msdn.microsoft.com/en-us/library/ms734665.aspx http://msdn.microsoft.com/en-us/library/ms734665.aspx

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在运行时停止/启动 WCF MEX 服务 的相关文章

随机推荐