我正在寻找WCF命名管道的最小示例(我希望有两个最小的应用程序,服务器和客户端,它们可以通过命名管道进行通信。)
Microsoft有一篇通过HTTP描述WCF的瑕疵文章 Getting Started Tutorial ,我正在寻找类似WCF和命名管道的东西。
我在互联网上发现了几个帖子,但它们有点“先进”。我需要一些最小的,只有强制性的功能,所以我可以添加我的代码并使应用程序正常工作。
如何替换它以使用命名管道?
<endpoint address="http://localhost:8000/ServiceModelSamples/Service/CalculatorService"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculator"
contract="ICalculator" name="WSHttpBinding_ICalculator">
<identity>
<userPrincipalName value="OlegPc\Oleg" />
</identity>
</endpoint>
如何替换它以使用命名管道?
// Step 1 of the address configuration procedure: Create a URI to serve as the base address.
Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");
// Step 2 of the hosting procedure: Create ServiceHost
ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
try
{
// Step 3 of the hosting procedure: Add a service endpoint.
selfHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
"CalculatorService");
// Step 4 of the hosting procedure: Enable metadata exchange.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
// Step 5 of the hosting procedure: Start (and then stop) the service.
selfHost.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
// Close the ServiceHostBase to shutdown the service.
selfHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
如何生成客户端以使用命名管道?
答案 0 :(得分:80)
我刚发现this excellent little tutorial。 断开链接(Cached version)
我也遵循微软的教程,这很好,但我也只需要管道。
正如您所看到的,您不需要配置文件和所有那些混乱的东西。
顺便说一下,他同时使用HTTP和管道。只需删除与HTTP相关的所有代码行,您就会得到一个纯粹的管道示例。
答案 1 :(得分:58)
试试这个。
这是服务部分。
[ServiceContract]
public interface IService
{
[OperationContract]
void HelloWorld();
}
public class Service : IService
{
public void HelloWorld()
{
//Hello World
}
}
这是代理
public class ServiceProxy : ClientBase<IService>
{
public ServiceProxy()
: base(new ServiceEndpoint(ContractDescription.GetContract(typeof(IService)),
new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/MyAppNameThatNobodyElseWillUse/helloservice")))
{
}
public void InvokeHelloWorld()
{
Channel.HelloWorld();
}
}
这是服务托管部分。
var serviceHost = new ServiceHost
(typeof(Service), new Uri[] { new Uri("net.pipe://localhost/MyAppNameThatNobodyElseWillUse") });
serviceHost.AddServiceEndpoint(typeof(IService), new NetNamedPipeBinding(), "helloservice");
serviceHost.Open();
Console.WriteLine("Service started. Available in following endpoints");
foreach (var serviceEndpoint in serviceHost.Description.Endpoints)
{
Console.WriteLine(serviceEndpoint.ListenUri.AbsoluteUri);
}
答案 2 :(得分:14)
查看我的highly simplified Echo example: 它旨在使用基本的HTTP通信,但可以通过编辑客户端和服务器的 app.config 文件轻松修改它以使用命名管道。进行以下更改:
编辑服务器的app.config文件,删除或注释掉http baseAddress 条目并添加新的 baseAddress 命名管道的条目(称为 net.pipe )。此外,如果您不打算将HTTP用于通信协议,请确保 serviceMetadata 和 serviceDebug 被注释掉或删除:
<configuration>
<system.serviceModel>
<services>
<service name="com.aschneider.examples.wcf.services.EchoService">
<host>
<baseAddresses>
<add baseAddress="net.pipe://localhost/EchoService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors></serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
编辑客户端的app.config文件,以便 basicHttpBinding 被注释掉或删除,并且 netNamedPipeBinding < / strong>条目已添加。您还需要更改 端点 条目以使用管道:
<configuration>
<system.serviceModel>
<bindings>
<netNamedPipeBinding>
<binding name="NetNamedPipeBinding_IEchoService"/>
</netNamedPipeBinding>
</bindings>
<client>
<endpoint address = "net.pipe://localhost/EchoService"
binding = "netNamedPipeBinding"
bindingConfiguration = "NetNamedPipeBinding_IEchoService"
contract = "EchoServiceReference.IEchoService"
name = "NetNamedPipeBinding_IEchoService"/>
</client>
</system.serviceModel>
</configuration>
上面的示例只能使用命名管道运行,但没有什么能阻止您使用多个协议来运行您的服务。 AFAIK,您应该能够让服务器使用命名管道和HTTP(以及其他协议)运行服务。
此外,客户端的 app.config 文件中的绑定也大大简化了。您可以调整许多不同的参数,只需指定 baseAddress ...
答案 3 :(得分:1)
我在互联网上的不同搜索结果中创建了这个简单的例子。
public static ServiceHost CreateServiceHost(Type serviceInterface, Type implementation)
{
//Create base address
string baseAddress = "net.pipe://localhost/MyService";
ServiceHost serviceHost = new ServiceHost(implementation, new Uri(baseAddress));
//Net named pipe
NetNamedPipeBinding binding = new NetNamedPipeBinding { MaxReceivedMessageSize = 2147483647 };
serviceHost.AddServiceEndpoint(serviceInterface, binding, baseAddress);
//MEX - Meta data exchange
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
serviceHost.Description.Behaviors.Add(behavior);
serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexNamedPipeBinding(), baseAddress + "/mex/");
return serviceHost;
}
使用上面的URI我可以在我的客户端中添加一个引用到Web服务。
答案 4 :(得分:-2)
我发现此站点确实很有帮助,示例项目的运行无需任何调整: https://dotnet-experience.blogspot.com/2012/02/inter-process-duplex-communication-with.html
请不要忘记在Windows功能中启用命名管道支持。本文在最佳答案中有一些效果不错的屏幕截图: WCF Named Pipe in Windows Service using App.Config
接受的解决方案中引用的项目无法在我的PC上按原样运行。我在app.config中尝试了一些修复程序,但仍然遇到以下异常:
System.InvalidOperationException:'服务 “ WpfWcfNamedPipeBinding.NamedPipeBindingService”的申请为零 (非基础设施)端点。这可能是因为没有配置 为您的应用程序找到文件,或者因为没有服务元素 在配置文件中可以找到与服务名称匹配的名称,或者 因为在service元素中没有定义端点。'