基于使用命名的 NetPipes 绑定分析终结点地址动态创建 WCF 服务主机

本文关键字:动态 地址 结点 创建 WCF 主机 服务 于使用 NetPipes 绑定 | 更新日期: 2023-09-27 18:36:53

需要一种方法让已知端点上的一个服务返回相对地址的字符串。然后,客户端可以使用这些相对地址连接到终结点。显然,这在某些方面类似于REST,但在这种情况下,使用NetNamedPipeBinding for IPC运行Windows服务,因此不需要HTTP。

不想提前创建终结点,因为可能会有大量的相对地址,其中只有客户端感兴趣的部分地址。

所有合同都是事先知道的。

尝试使用AddressFilterMode找到解决方案,但不确定如何配置新的绑定,以便客户端连接到它,UriTemplate,但不想使用HTTP框架。没有研究过路由服务,因为仅限于.Net 3.5。

客户端的伪代码如下所示...

namespace Testing
{
    class RunTest
    {
        static void Test()
        {
            NetNamedPipeBinding namedpipe = new NetNamedPipeBinding();
            ChannelFactory<Contracts.IRoot> factoryRoot =
                new ChannelFactory<Contracts.IRoot>(
                namedpipe
                , new EndpointAddress("net.pipe://localhost/root");
            );
            Contracts.IRoot root = factoryRoot.CreateChannel();
            ICommunicationObject commsRoot = root as ICommunicationObject;
            commsRoot.Open();
            // Service examines address and creates Endpoint dynamically.
            string address = root.SomeFunctionWhichGetsARelativeAddress();
            // IBar service routes endpoint requests internally based on
            // "address" variable.
            ChannelFactory<Contracts.IBar> factoryBar = 
                new ChannelFactory<Contracts.IBar>(
                namedpipe
                , new EndpointAddress("net.pipe://localhost/root/IBar/" +
                                       address)
            );
            Contracts.IBar bar = factoryBar.CreateChannel();
            bar.DoSomething();
        }
    } // Ends class RunTest
} // Ends namespace Testing

基于使用命名的 NetPipes 绑定分析终结点地址动态创建 WCF 服务主机

邮件过滤器是要走的路。您可以使用"前缀"或创建自定义。

WCF 深入寻址

从本文的"邮件筛选器"部分:

。它使用消息过滤器来确定匹配的端点(如果有) 存在。您可以选择要使用的邮件过滤器,也可以提供 你自己的。这种灵活性使您能够摆脱 使用 Windows 通信时的传统调度模型 实现传统 SOAP 以外的其他内容的基础 — 实例中,此处描述的技术使您能够实现 Windows Communication Foundation 上的 REST/POX 样式服务 消息传递基础。

顺便说一下,好问题。我学到了一些东西试图弄清楚这一点。

AddressFilterMode.Prefix 可能就足够了。可以使用的实际端点可以通过OperationContext.Current.IncomingMessageHeaders.To

帮助程序代码可以分析终结点,并从那里执行任何必要的内部处理。希望服务器端有一些可扩展性可以简化该代码。

主机的伪代码:

namespace Services
{
    [System.ServiceModel.ServiceBehavior(AddressFilterMode =
         System.ServiceModel.AddressFilterMode.Prefix)]
    class BarService : Contracts.IBar
    {
        #region IBar Members
        public void DoSomething()
        {
            System.Uri endpoint = System.ServiceModel.OperationContext.Current.IncomingMessageHeaders.To;
            Console.WriteLine("DoSomething endpoint: {0}", endpoint);
        }
    } // Ends class BarService
} // Ends namespace Services
class RunHost
{
    static void HostIBar()
    {
        System.Uri uriBase = new System.Uri("net.pipe://localhost");
        System.ServiceModel.ServiceHost hostBar =
            new System.ServiceModel.ServiceHost(
            typeof(Services.BarService),
            uriBase);
        hostBar.AddServiceEndpoint(
              typeof(Contracts.IBar) // Type implementedContract
            , namedpipeBinding // System.ServiceModel.Channels.Binding binding
            , "root/IBar" //string address
        );
        hostBar.Open();
        Console.WriteLine("Press <ENTER> to stop...");
        Console.ReadLine();
    }
}

更正:我最初说这不会将"net.pipe://localhost/root/IBar/1""net.pipe://localhost/root/IBar/2"视为不同的端点,但它确实如此。每个实例都会导致创建和调用自己的 WCF 服务实例。

另一个更改是在 URL 样式查询参数中对数据进行编码,而不是将其嵌入到路径中。 例如:使用 HttpUtility.ParseQueryString "net.pipe://localhost/root/IBar?something=1&somethingelse=11""net.pipe://localhost/root/IBar?something=2&somethingelse=22"