Procedimiento para hospedar un servicio WCF en WAS
Este tema describe los pasos básicos necesarios para crear un servicio Windows Communication Foundation (WCF) hospedado de Windows Process Activation Services (también conocido como WAS). WAS es el nuevo servicio de activación de procesos que es una generalización de las características de Internet Information Services (IIS) que funcionan con protocolos de transporte no HTTP. WCF usa la interfaz de adaptador del cliente de escucha para comunicar solicitudes de activación que se reciben a través de protocolos no HTTP que admite WCF, como TCP, canalizaciones con nombre y Message Queue Server.
Esta opción de hospedaje necesita que los componentes de activación WAS se instalen y configuren correctamente, pero no necesita que se escriba ningún código de hospedaje como parte de la aplicación. Para obtener más información sobre el procedimiento para instalar y configurar WAS, consulte Procedimiento para instalar y configurar componentes de activación WCF.
Advertencia
La activación de WAS no se admite si la canalización de procesamiento de solicitudes del servidor web está establecida en el modo clásico. La canalización de procesamiento de solicitudes del servidor web debe estar establecida en el modo integrado si debe usarse la activación de WAS.
Cuando un servicio WCF se hospeda en WAS, los enlaces estándar se usan de forma habitual. Sin embargo, al utilizar NetTcpBinding y NetNamedPipeBinding para configurar un servicio hospedado en WAS, se debe satisfacer una restricción. Cuando extremos diferentes utilizan el mismo transporte, las configuraciones del enlace tienen que coincidir en las siete propiedades siguientes:
ConnectionBufferSize
ChannelInitializationTimeout
MaxPendingConnections
MaxOutputDelay
MaxPendingAccepts
ConnectionPoolSettings.IdleTimeout
ConnectionPoolSettings.MaxOutboundConnectionsPerEndpoint
De lo contrario, el extremo que se inicializa primero siempre determina los valores de estas propiedades y los extremos agregados después producen una ServiceActivationException si no coinciden con esos valores.
Para la copia de origen de este ejemplo, consulte Activación de TCP.
Creación de un servicio básico hospedado por WAS
Defina un contrato de servicios para el tipo de servicio.
[ServiceContract] public interface ICalculator { [OperationContract] double Add(double n1, double n2); [OperationContract] double Subtract(double n1, double n2); [OperationContract] double Multiply(double n1, double n2); [OperationContract] double Divide(double n1, double n2); }
Implemente el contrato de servicios en una clase de servicio. Observe que la información de enlace o dirección no se especifica en ninguna parte de la implementación del servicio. Además, el código tiene que escribirse para recuperar esa información del archivo de configuración.
public class CalculatorService : ICalculator { public double Add(double n1, double n2) { return n1 + n2; } public double Subtract(double n1, double n2) { return n1 - n2; } public double Multiply(double n1, double n2) { return n1 * n2; } public double Divide(double n1, double n2) { return n1 / n2; } }
Cree un archivo Web.config para definir el enlace NetTcpBinding que van a usar los extremos
CalculatorService
.<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <netTcpBinding> <binding portSharingEnabled="true"> <security mode="None" /> </binding> </netTcpBinding> </bindings> </system.serviceModel> </configuration>
Cree un archivo Service.svc que contenga el código siguiente.
<%@ServiceHost language=c# Service="CalculatorService" %>
Coloque el archivo Service.svc en su directorio virtual de IIS.
Creación de un cliente para que utilice el servicio
Use la Herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe) desde la línea de comandos para generar código a partir de metadatos del servicio.
Svcutil.exe <service's Metadata Exchange (MEX) address or HTTP GET address>
El cliente que se genera contiene la interfaz
ICalculator
que define el contrato de servicios que la implementación del cliente debe cumplir.//Generated interface defining the ICalculator contract [System.ServiceModel.ServiceContractAttribute( Namespace="http://Microsoft.ServiceModel.Samples", ConfigurationName="Microsoft.ServiceModel.Samples.ICalculator")] public interface ICalculator { [System.ServiceModel.OperationContractAttribute( Action="http://Microsoft.ServiceModel.Samples/ICalculator/Add", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/AddResponse")] double Add(double n1, double n2); [System.ServiceModel.OperationContractAttribute( Action="http://Microsoft.ServiceModel.Samples/ICalculator/Subtract", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/SubtractResponse")] double Subtract(double n1, double n2); [System.ServiceModel.OperationContractAttribute( Action="http://Microsoft.ServiceModel.Samples/ICalculator/Multiply", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/MultiplyResponse")] double Multiply(double n1, double n2); [System.ServiceModel.OperationContractAttribute( Action="http://Microsoft.ServiceModel.Samples/ICalculator/Divide", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/DivideResponse")] double Divide(double n1, double n2); }
La aplicación de cliente generada también contiene la implementación de
ClientCalculator
. Observe que la información de enlace y dirección no se especifica en ninguna parte de la implementación del servicio. Además, el código tiene que escribirse para recuperar esa información del archivo de configuración.// Implementation of the CalculatorClient public partial class CalculatorClient : System.ServiceModel.ClientBase<Microsoft.ServiceModel.Samples.ICalculator>, Microsoft.ServiceModel.Samples.ICalculator { public CalculatorClient() { } public CalculatorClient(string endpointConfigurationName) : base(endpointConfigurationName) { } public CalculatorClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CalculatorClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CalculatorClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public double Add(double n1, double n2) { return base.Channel.Add(n1, n2); } public double Subtract(double n1, double n2) { return base.Channel.Subtract(n1, n2); } public double Multiply(double n1, double n2) { return base.Channel.Multiply(n1, n2); } public double Divide(double n1, double n2) { return base.Channel.Divide(n1, n2); } }
Svcutil.exe también genera la configuración del cliente que utiliza el NetTcpBinding. Este archivo se debería nombrar en el archivo App.config al utilizar Visual Studio.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <netTcpBinding> <binding name="NetTcpBinding_ICalculator"> <security mode="None"/> </binding> </netTcpBinding> </bindings> <client> <endpoint address="net.tcp://localhost/servicemodelsamples/service.svc" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ICalculator" contract="ICalculator" name="NetTcpBinding_ICalculator" /> </client> </system.serviceModel> </configuration>
Cree una instancia de
ClientCalculator
en una aplicación y, a continuación, llame a las operaciones del servicio.//Client implementation code. class Client { static void Main() { // Create a client with given client endpoint configuration CalculatorClient client = new CalculatorClient(); // Call the Add service operation. double value1 = 100.00D; double value2 = 15.99D; double result = client.Add(value1, value2); Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result); // Call the Subtract service operation. value1 = 145.00D; value2 = 76.54D; result = client.Subtract(value1, value2); Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result); // Call the Multiply service operation. value1 = 9.00D; value2 = 81.25D; result = client.Multiply(value1, value2); Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result); // Call the Divide service operation. value1 = 22.00D; value2 = 7.00D; result = client.Divide(value1, value2); Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result); //Closing the client gracefully closes the connection and cleans up resources client.Close(); Console.WriteLine(); Console.WriteLine("Press <ENTER> to terminate client."); Console.ReadLine(); } }
Compile y ejecute el cliente.