Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Toda la comunicación con un servicio de Windows Communication Foundation (WCF) se produce a través de sus puntos de conexión. Cada ServiceEndpoint contiene un Address, un Bindingy un Contract. El contrato especifica qué operaciones están disponibles. El enlace especifica cómo comunicarse con el servicio y la dirección especifica dónde buscar el servicio. Cada punto de conexión debe tener una dirección única. La dirección del punto de conexión se representa mediante la EndpointAddress clase , que contiene un identificador uniforme de recursos (URI) que representa la dirección del servicio, , Identityque representa la identidad de seguridad del servicio y una colección de opcionales Headers. Los encabezados opcionales proporcionan información de direccionamiento más detallada para identificar o interactuar con el punto de conexión. Por ejemplo, los encabezados pueden indicar cómo procesar un mensaje entrante, donde el punto de conexión debe enviar un mensaje de respuesta o la instancia de un servicio que se va a usar para procesar un mensaje entrante de un usuario determinado cuando hay varias instancias disponibles.
Definición de una dirección de punto de conexión
En WCF, un modelo EndpointAddress modela una referencia de punto de conexión (EPR) tal como se define en el estándar WS-Addressing.
El URI de dirección para la mayoría de los transportes tiene cuatro partes. Por ejemplo, este URI http://www.fabrikam.com:322/mathservice.svc/secureEndpoint
tiene las cuatro partes siguientes:
Esquema: http:
Máquina:
www.fabrikam.com
(Opcional) Puerto: 322
Ruta de acceso: /mathservice.svc/secureEndpoint
Parte del modelo EPR es que cada referencia de punto de conexión puede llevar algunos parámetros de referencia que agregan información de identificación adicional. En WCF, estos parámetros de referencia se modelan como instancias de la AddressHeader clase .
La dirección del punto de conexión de un servicio se puede especificar de forma imperativa mediante código o mediante declaración a través de la configuración. La definición de puntos de conexión en el código no suele ser práctica porque los enlaces y direcciones de un servicio implementado suelen ser diferentes de los usados mientras se desarrolla el servicio. Por lo general, es más práctico definir puntos de conexión de servicio mediante la configuración en lugar de código. Mantener la información de enlace y direccionamiento fuera del código les permite cambiar sin tener que volver a compilar y volver a implementar la aplicación. Si no se especifica ningún punto de conexión en el código o en la configuración, el tiempo de ejecución agrega un punto de conexión predeterminado en cada dirección base para cada contrato implementado por el servicio.
Hay dos maneras de especificar direcciones de punto de conexión para un servicio en WCF. Puede especificar una dirección absoluta para cada punto de conexión asociado al servicio o puede proporcionar una dirección base para el ServiceHost de un servicio y, a continuación, especificar una dirección para cada punto de conexión asociado a este servicio que se define en relación con esta dirección base. Puede usar cada uno de estos procedimientos para especificar las direcciones de punto de conexión de un servicio en la configuración o en el código. Si no especifica una dirección relativa, el servicio usa la dirección base. También puede tener varias direcciones base para un servicio, pero cada servicio solo se permite una dirección base para cada transporte. Si tiene varios puntos de conexión, cada uno de los cuales está configurado con un enlace diferente, sus direcciones deben ser únicas. Los puntos de conexión que utilizan la misma vinculación pero contratos diferentes pueden usar la misma dirección.
Al hospedar con IIS, usted no administra la instancia ServiceHost. La dirección base es siempre la dirección especificada en el archivo .svc del servicio al hospedarse en IIS. Por lo tanto, debe usar direcciones de punto de conexión relativas para los puntos de conexión de servicio hospedados en IIS. Proporcionar una dirección de punto de conexión completamente calificada puede provocar errores en la implementación del servicio. Para obtener más información, vea Deploying an Internet Information Services-Hosted WCF Service.
Definición de direcciones de punto de conexión en configuración
Para definir un punto de conexión en un archivo de configuración, use el <elemento endpoint> .
<configuration>
<system.serviceModel>
<services>
<service name="UE.Samples.HelloService"
behaviorConfiguration="HelloServiceBehavior">
<endpoint address="/Address1"
binding="basicHttpBinding"
contract="UE.Samples.IHello"/>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="HelloServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Cuando se llama al método Open (es decir, cuando la aplicación de hospedaje intenta iniciar el servicio), el sistema busca un elemento <servicio> con un atributo de nombre que especifica "UE.Samples.HelloService". Si se encuentra el elemento de servicio<, el> sistema carga la clase especificada y crea puntos de conexión mediante las definiciones de punto de conexión proporcionadas en el archivo de configuración. Este mecanismo permite cargar e iniciar un servicio con dos líneas de código al tiempo que mantiene la información de enlace y direccionamiento fuera del código. La ventaja de este enfoque es que estos cambios se pueden realizar sin tener que volver a compilar ni volver a implementar la aplicación.
Los encabezados opcionales se declaran en un elemento <headers>. A continuación se muestra un ejemplo de los elementos usados para especificar puntos de conexión para un servicio en un archivo de configuración que distingue entre dos encabezados: clientes "Gold" de http://tempuri1.org/
y "Estándar" de http://tempuri2.org/
. El cliente que llama a este servicio debe tener los encabezados< adecuados> en su archivo de configuración.
<configuration>
<system.serviceModel>
<services>
<service name="UE.Samples.HelloService"
behaviorConfiguration="HelloServiceBehavior">
<endpoint address="/Address1"
binding="basicHttpBinding"
contract="UE.Samples.IHello">
<headers>
<Member xmlns="http://tempuri1.org/">Gold</Member>
</headers>
</endpoint>
<endpoint address="/Address2"
binding="basicHttpBinding"
contract="UE.Samples.IHello">
<headers>
<Member xmlns="http://tempuri2.org/">Silver</Member>
</headers>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="HelloServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Los encabezados también se pueden establecer en mensajes individuales en lugar de en todos los mensajes de un punto de conexión (como se mostró anteriormente). Esto se hace mediante OperationContextScope para crear un nuevo contexto en una aplicación cliente para agregar un encabezado personalizado al mensaje saliente, como se muestra en el ejemplo siguiente.
SampleServiceClient wcfClient = new SampleServiceClient(new InstanceContext(this));
try
{
using (OperationContextScope scope = new OperationContextScope(wcfClient.InnerChannel))
{
MessageHeader header
= MessageHeader.CreateHeader(
"Service-Bound-CustomHeader",
"http://Microsoft.WCF.Documentation",
"Custom Happy Value."
);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
// Making calls.
Console.WriteLine("Enter the greeting to send: ");
string greeting = Console.ReadLine();
//Console.ReadLine();
header = MessageHeader.CreateHeader(
"Service-Bound-OneWayHeader",
"http://Microsoft.WCF.Documentation",
"Different Happy Value."
);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
// One-way
wcfClient.Push(greeting);
this.wait.WaitOne();
// Done with service.
wcfClient.Close();
Console.WriteLine("Done!");
Console.ReadLine();
}
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message);
Console.ReadLine();
wcfClient.Abort();
}
Dim wcfClient As New SampleServiceClient(New InstanceContext(Me))
Try
Using scope As New OperationContextScope(wcfClient.InnerChannel)
Dim header As MessageHeader = MessageHeader.CreateHeader("Service-Bound-CustomHeader", _
"http://Microsoft.WCF.Documentation", "Custom Happy Value.")
OperationContext.Current.OutgoingMessageHeaders.Add(header)
' Making calls.
Console.WriteLine("Enter the greeting to send: ")
Dim greeting As String = Console.ReadLine()
'Console.ReadLine();
header = MessageHeader.CreateHeader("Service-Bound-OneWayHeader", _
"http://Microsoft.WCF.Documentation", "Different Happy Value.")
OperationContext.Current.OutgoingMessageHeaders.Add(header)
' One-way
wcfClient.Push(greeting)
Me.wait.WaitOne()
' Done with service.
wcfClient.Close()
Console.WriteLine("Done!")
Console.ReadLine()
End Using
Catch timeProblem As TimeoutException
Console.WriteLine("The service operation timed out. " & timeProblem.Message)
Console.ReadLine()
wcfClient.Abort()
Catch commProblem As CommunicationException
Console.WriteLine("There was a communication problem. " & commProblem.Message)
Console.ReadLine()
wcfClient.Abort()
End Try
Dirección del punto de conexión en metadatos
Una dirección de punto de conexión se representa en el Lenguaje de Descripción de Servicios Web (WSDL) como un elemento WS-Addressing EndpointReference
(EPR) dentro del elemento del punto de conexión wsdl:port
correspondiente. El EPR contiene la dirección del punto de conexión, así como cualquier propiedad de dirección. Tenga en cuenta que el EPR dentro wsdl:port
reemplaza soap:Address
como se muestra en el ejemplo siguiente.
Definición de direcciones de punto de conexión en código
Se puede crear una dirección de punto de conexión en el código con la EndpointAddress clase . El URI especificado para la dirección del extremo puede ser una ruta de acceso completa o una ruta de acceso relativa a la dirección base del servicio. El código siguiente muestra cómo crear una instancia de la EndpointAddress clase y agregarla a la ServiceHost instancia que hospeda el servicio.
En el ejemplo siguiente se muestra cómo especificar la dirección completa del punto de conexión en el código.
Uri baseAddress = new Uri("http://localhost:8000/HelloService");
string address = "http://localhost:8000/HelloService/MyService";
using (ServiceHost serviceHost = new ServiceHost(typeof(HelloService), baseAddress))
{
serviceHost.AddServiceEndpoint(typeof(IHello), new BasicHttpBinding(), address);
serviceHost.Open();
Console.WriteLine("Press <enter> to terminate service");
Console.ReadLine();
serviceHost.Close();
}
En el ejemplo siguiente se muestra cómo agregar una dirección relativa ("MyService") a la dirección base del host del servicio.
Uri baseAddress = new Uri("http://localhost:8000/HelloService");
using (ServiceHost serviceHost = new ServiceHost(typeof(HelloService), baseAddress))
{
serviceHost.AddServiceEndpoint(typeof(IHello), new BasicHttpBinding(), "MyService");
serviceHost.Open();
Console.WriteLine("Press <enter> to terminate service");
Console.ReadLine();
serviceHost.Close();
}
Nota:
Las propiedades de ServiceDescription en la aplicación de servicio no se deben modificar después del método de OnOpening en ServiceHostBase. Algunos miembros, como la Credentials propiedad y los AddServiceEndpoint
métodos en ServiceHostBase y ServiceHost, lanzan una excepción si se modifican después de ese punto. Otros le permiten modificarlos, pero el resultado no está definido.
De igual forma, en el cliente no se deben modificar los valores ServiceEndpoint después de la llamada a OnOpening en ChannelFactory. La Credentials propiedad produce una excepción si se modifica después de ese punto. Los demás valores de descripción del cliente se pueden modificar sin errores, pero el resultado no está definido.
Tanto para el servicio como para el cliente, se recomienda modificar la descripción antes de llamar a Open.
Uso de puntos de conexión predeterminados
Si no se especifica ningún punto de conexión en el código o en la configuración, el tiempo de ejecución proporciona puntos de conexión predeterminados agregando un punto de conexión predeterminado en cada dirección base para cada contrato de servicio implementado por el servicio. La dirección base se puede especificar en el código o en la configuración, y los puntos de conexión predeterminados se agregan cuando se llama a Open en el ServiceHost.
Si se proporcionan de forma explícita los puntos de conexión, los puntos de conexión predeterminados se pueden agregar llamando a AddDefaultEndpoints en ServiceHost antes de llamar a Open. Para obtener más información sobre los puntos de conexión, enlaces y comportamientos predeterminados, vea Configuración simplificada y Configuración simplificada para servicios WCF.