基于使用命名的 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
邮件过滤器是要走的路。您可以使用"前缀"或创建自定义。
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"