c# - WCF named pipe example example
named-pipes (4)
Creé este sencillo ejemplo de diferentes resultados de búsqueda en Internet.
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;
}
Usando el URI anterior, puedo agregar una referencia en mi cliente al servicio web.
Estoy buscando un ejemplo mínimo de WCF Named Pipes (espero dos aplicaciones mínimas, servidor y cliente, que se puedan comunicar a través de un conducto con nombre).
Microsoft tiene el artículo de introducción Tutorial que describe WCF a través de HTTP, y estoy buscando algo similar sobre WCF y canalizaciones con nombre.
He encontrado varias publicaciones en Internet, pero están un poco "avanzadas". Necesito algo mínimo, solo funcionalidad obligatoria, por lo que puedo agregar mi código y hacer que la aplicación funcione.
¿Cómo puedo reemplazar eso para usar un tubo con nombre?
<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>
¿Cómo puedo reemplazar eso para usar un tubo con nombre?
// 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();
}
¿Cómo puedo generar un cliente para usar un conducto con nombre?
Mira mi ejemplo de Echo altamente simplificado : está diseñado para usar comunicación HTTP básica, pero puede modificarse fácilmente para usar canalizaciones con nombre editando los archivos app.config para el cliente y el servidor. Realice los siguientes cambios:
Edite el archivo app.config del servidor, elimine o comente la entrada http baseAddress y agregue una nueva entrada baseAddress para la tubería con nombre (llamada net.pipe ). Además, si no tiene la intención de usar HTTP para un protocolo de comunicación, asegúrese de que serviceMetadata y serviceDebug estén comentados o eliminados:
<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>
Edite el archivo app.config del cliente para que el basicHttpBinding se comente o elimine y se agregue una entrada netNamedPipeBinding . También necesitará cambiar la entrada del punto final para usar la tubería:
<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>
El ejemplo anterior solo se ejecutará con canalizaciones con nombre, pero nada le impide utilizar múltiples protocolos para ejecutar su servicio. AFAIK, deberías poder hacer que un servidor ejecute un servicio usando tanto canalizaciones con nombre como HTTP (y otros protocolos).
Además, el enlace en el archivo app.config del cliente está muy simplificado. Hay muchos parámetros diferentes que puede ajustar, además de solo especificar la baseAddress ...
Prueba esto.
Aquí está la parte del servicio.
[ServiceContract]
public interface IService
{
[OperationContract]
void HelloWorld();
}
public class Service : IService
{
public void HelloWorld()
{
//Hello World
}
}
Aquí está el Proxy
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();
}
}
Y aquí está la parte de alojamiento del servicio.
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);
}
Acabo de encontrar este excelente pequeño tutorial . enlace roto ( versión en caché )
También seguí el tutorial de Microsoft, que es bueno, pero solo necesitaba tuberías también.
Como puede ver, no necesita archivos de configuración y todas esas cosas desordenadas.
Por cierto, usa HTTP y pipes. Simplemente elimine todas las líneas de código relacionadas con HTTP, y obtendrá un ejemplo de tubería pura.