Compartir a través de


Unidireccional

El ejemplo unidireccional muestra un contacto del servicio con operaciones de servicio unidireccionales. El cliente no espera a que se completen las operaciones de servicio, como sucede con las operaciones de servicio bidireccionales. Este ejemplo se basa en Guía de inicio y utiliza la wsHttpBinding vinculación. El servicio de este ejemplo es una aplicación de consola autohospedada para permitirle observar el servicio que recibe y procesa las solicitudes. El cliente también es una aplicación de consola.

Nota:

El procedimiento de instalación y las instrucciones de compilación de este ejemplo se encuentran al final de este tema.

Para crear un contrato de servicio unidireccional, defina su contrato de servicio, aplique la clase OperationContractAttribute en cada operación y establezca IsOneWay como true, como se muestra en el código de ejemplo siguiente:

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOneWayCalculator
{
    [OperationContract(IsOneWay=true)]
    void Add(double n1, double n2);
    [OperationContract(IsOneWay = true)]
    void Subtract(double n1, double n2);
    [OperationContract(IsOneWay = true)]
    void Multiply(double n1, double n2);
    [OperationContract(IsOneWay = true)]
    void Divide(double n1, double n2);
}

Para demostrar que el cliente no espera a que se completen las operaciones de servicio, el código de servicio de este ejemplo implementa un retraso de cinco segundos, como se muestra en el código de ejemplo siguiente:

// This service class implements the service contract.
// This code writes output to the console window.
 [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
    InstanceContextMode = InstanceContextMode.PerCall)]
public class CalculatorService : IOneWayCalculator
{
    public void Add(double n1, double n2)
    {
        Console.WriteLine("Received Add({0},{1}) - sleeping", n1, n2);
        System.Threading.Thread.Sleep(1000 * 5);
        double result = n1 + n2;
        Console.WriteLine("Processing Add({0},{1}) - result: {2}", n1, n2, result);
    }
    ...
}

Cuando el cliente llama al servicio, la llamada se devuelve sin esperar a que se complete la operación del servicio.

Al ejecutar el ejemplo, las actividades de cliente y servicio se muestran en las ventanas de servicio y consola de cliente. Puede ver que el servicio recibe mensajes del cliente. Presione ENTRAR en cada ventana de consola para apagar tanto el servicio como el cliente.

El cliente finaliza delante del servicio, mostrando que un cliente no espera a que las operaciones de servicio unidireccional se completen. La salida del cliente es la siguiente:

Add(100,15.99)
Subtract(145,76.54)
Multiply(9,81.25)
Divide(22,7)

Press <ENTER> to terminate client.

Se muestra la siguiente salida de servicio:

The service is ready.
Press <ENTER> to terminate service.

Received Add(100,15.99) - sleeping
Received Subtract(145,76.54) - sleeping
Received Multiply(9,81.25) - sleeping
Received Divide(22,7) - sleeping
Processing Add(100,15.99) - result: 115.99
Processing Subtract(145,76.54) - result: 68.46
Processing Multiply(9,81.25) - result: 731.25
Processing Divide(22,7) - result: 3.14285714285714

Nota:

HTTP es, por definición, un protocolo de solicitud/respuesta; cuando se realiza una solicitud, se devuelve una respuesta. Esto es cierto incluso para una operación de servicio unidireccional que se expone a través de HTTP. Cuando se llama a la operación, el servicio devuelve un código de estado HTTP de 202 antes de que se haya ejecutado la operación de servicio. Este código de estado significa que la solicitud se ha aceptado para su procesamiento, pero el procesamiento aún no se ha completado. El cliente que llamó a la operación permanece bloqueado hasta que recibe la respuesta 202 del servicio. Esto puede provocar un comportamiento inesperado cuando se envían varios mensajes unidireccionales mediante un enlace configurado para usar sesiones. El wsHttpBinding enlace usado en este ejemplo está configurado para usar sesiones de forma predeterminada para establecer un contexto de seguridad. De forma predeterminada, se garantiza que los mensajes de una sesión lleguen en el orden en que se envían. Debido a esto, cuando se envía el segundo mensaje de una sesión, no se procesa hasta que se haya procesado el primer mensaje. El resultado de esto es que el cliente no recibe la respuesta 202 de un mensaje hasta que se haya completado el procesamiento del mensaje anterior. Parece, por tanto, que el cliente se bloquea en cada llamada de operación subsiguiente. Para evitar este comportamiento, este ejemplo configura el tiempo de ejecución para enviar mensajes simultáneamente a distintas instancias para su procesamiento. El ejemplo establece InstanceContextMode en PerCall para que una instancia diferente pueda procesar cada mensaje. ConcurrencyMode se establece en Multiple para permitir que más de un subproceso envíe mensajes a la vez.

Para configurar, compilar y ejecutar el ejemplo

  1. Asegúrese de que ha realizado el procedimiento de instalación única para los ejemplos de Windows Communication Foundation.

  2. Para compilar el código C# o Visual Basic .NET Edition de la solución, siga las instrucciones de Building the Windows Communication Foundation Samples.

  3. Para ejecutar el ejemplo en una configuración de una máquina única o entre máquinas, siga las instrucciones de Ejecución de los ejemplos de Windows Communication Foundation.

Nota:

Ejecute el servicio antes de ejecutar el cliente y apague el cliente antes de apagar el servicio. Esto evita una excepción de cliente cuando el cliente no puede cerrar la sesión de seguridad limpiamente porque el servicio ha desaparecido.