Share via


Ejemplo de servicio de flujo de trabajo dúplex

Download sample

Este ejemplo muestra cómo realizar la comunicación dúplex asincrónica entre dos servicios que se comunican. Este ejemplo también muestra cómo realizar la comunicación de host local a flujo de trabajo utilizando mensajes. Mientras se ejecuta comunicación dúplex entre dos servicios, los dos servicios deben intercambiar un contexto antes de que la comunicación pueda producirse en ambas direcciones. El servicio que inicia la comunicación recibe el contexto en la respuesta a su mensaje. Para admitir la comunicación del servicio receptor al servicio iniciador, el servicio iniciador debe enviar su información de contexto en el primer mensaje.

Nota

Para generar y ejecutar este ejemplo, es necesario que esté instalado .NET Framework versión 3.5. Para abrir los archivos de solución y proyecto se necesita Visual Studio 2008.

Para obtener más información acerca de que prepara este ejemplo, consulte Procedimiento de instalación único para ejemplos de Windows Communication Foundation.

Los mensajes también se utilizan para la comunicación entre el host local y el servicio. El host local expone un extremo conocido que el servicio puede utilizar para volver a llamar. Este ejemplo implementa un tipo LocalWorkflowServiceHost que proporciona la funcionalidad para crear el agente de escucha local, así como el host de servicio de flujo de trabajo para el servicio hospedado.

Arquitectura de ejemplo de servicio de flujo de trabajo de dúplex

Este ejemplo incluye las siguientes entidades que se comunican:

  • Host del Cliente

    El host del cliente se comunica con el flujo de trabajo del cliente llamando a operaciones en IReverseContract. Cuando el host del cliente llama primero a la operación BeginWork, se crea el flujo de trabajo del cliente. En respuesta a la operación BeginWork, el flujo de trabajo del cliente devuelve un mensaje que incluye el contexto para el flujo de trabajo del cliente. El canal que el host crea para comunicarse con el flujo de trabajo del cliente tiene ahora el contexto para una comunicación posterior. Este ejemplo muestra cómo el host del cliente utiliza el mismo canal para enviar varios elementos de trabajo al flujo de trabajo del cliente.

    Para que el flujo de trabajo se comunique con el host del cliente, el host del cliente tiene un extremo conocido en el que realiza escuchas. En este ejemplo, ese extremo conocido se denomina HostEndPoint. LocalWorkflowServiceHost se utiliza para crear ese extremo conocido para el host del cliente así como el host de servicio de flujo de trabajo para el flujo de trabajo del cliente.

    LocalWorkflowServiceHost localHost = new LocalWorkflowServiceHost(typeof(ClientWorkflow),new ClientHost());
    localHost.WorkflowRuntime.WorkflowTerminated += 
    delegate(object sender, WorkflowTerminatedEventArgs e) 
    {
        Console.WriteLine("WorkflowTerminated: " + e.Exception.Message);
    };
    localHost.WorkflowRuntime.WorkflowCompleted += 
    delegate(object sender, WorkflowCompletedEventArgs e) 
    { 
        Console.WriteLine("WorkflowCompleted: " + 
                         e.WorkflowInstance.InstanceId.ToString()); 
    };
    localHost.Open();
    
  • Flujo de trabajo del Cliente (se expone como un servicio)

    El flujo de trabajo del cliente implementa IReverseContract. El flujo de trabajo del servicio utiliza esto, como se muestra en la ilustración anterior, para comunicarse con el flujo de trabajo del cliente. El flujo de trabajo del cliente llama primero a la operación BeginWorkflow, que crea el flujo de trabajo del servicio. La respuesta devuelve el contexto para el flujo de trabajo del servicio, que se utiliza en subsiguientes comunicaciones de flujo de trabajo de cliente con el flujo de trabajo del servicio. Como parte de la operación BeginWorkflow, el flujo de trabajo del cliente pasa su propia referencia del extremo, que contiene la dirección del extremo así como los encabezados de contexto, al flujo de trabajo del servicio. El flujo de trabajo del servicio utiliza esta dirección del extremo para comunicarse de forma asincrónica con el flujo de trabajo del cliente.

    El controlador de eventos WaitForBeginWork en el estado inicial implementa una actividad de código denominada DoSetReturnAddress. Esta actividad establece la referencia del extremo, que se envía al flujo de trabajo del servicio, tal y como se muestra en el ejemplo siguiente.

    private void SetReturnAddress(object sender, EventArgs e)
    {
        EndpointAddress epr = 
                  ContextManager.CreateEndpointAddress(ReturnUri, 
                                  this.ReceiveWorkItemComplete);
        ReturnAddress = EndpointAddress10.FromEndpointAddress(epr);
        DebugOutput("[ClientWorkflow:SetReturnAddress] " + 
                              epr.Headers[0].GetValue<string>());
    }
    
  • Host de servicio

    Este ejemplo implementa un host de servicio de flujo de trabajo. Abre un agente de escucha que escucha las solicitudes del cliente. La primera solicitud del cliente crea una instancia del flujo de trabajo del servicio. Todas las solicitudes subsiguientes se enrutan a la misma instancia de flujo de trabajo porque las solicitudes llevan el contexto en el encabezado del mensaje.

  • Flujo de trabajo de Servicio (se expone como un servicio)

    El flujo de trabajo del servicio implementa IForwardContract . El flujo de trabajo del servicio en la operación BeginWorkflow recibe la referencia del extremo para el flujo de trabajo del cliente. El flujo de trabajo del servicio aplica esa referencia del extremo a la actividad Send que envía de forma asincrónica un mensaje al flujo de trabajo del cliente. El controlador de eventos WaitForBeginWorkflow proporciona la actividad BeginWorkflow Receive. Dentro de la actividad Receive existe una actividad de código denominada ApplyReturnAddress, que utiliza el remite en la actividad Send para enviar un mensaje al flujo de trabajo del cliente, tal y como muestra el siguiente código.

    private void ApplyReturnAddress(object sender, EventArgs e)
    {
        // apply ReturnAddress to ReverseEndpoint
        EndpointAddress epr = ReturnAddress.ToEndpointAddress();
        ContextManager.ApplyEndpointAddress(
                              this.SendWorkItemComplete, epr);
        DebugOutput("[ServiceWorkflow:ApplyReturnAddress] " + 
                           epr.Headers[0].GetValue<string>());
    }
    

    La clase LocalWorkflowServiceHost crea la infraestructura necesaria para la comunicación host a flujo de trabajo. El servicio del flujo de trabajo local realiza dos tareas principales:

    • Crea un agente de escucha local para que el host escuche los mensajes del flujo de trabajo.

    • Crea WorkflowServiceHost para crear un agente de escucha para el flujo de trabajo.

    La clase también proporciona funciones de auxiliar para que el host mantenga el contexto que se utiliza para comunicarse con el flujo de trabajo. Si el host recicla, este contexto se utiliza para comunicarse con la instancia de flujo de trabajo.

El proyecto WorkflowServiceUtility proporciona todas las funciones de auxiliar que se exigen para manipular el contexto. Proporciona las funciones para extraer el contexto del canal, aplicar contexto a un canal y aplicar una dirección de extremo a la actividad Send.

Para configurar, generar y ejecutar el ejemplo

  1. Para instalar los proveedores de persistencia, ejecute el script CreateStores.cmd situado en el tema Procedimiento de instalación único para ejemplos de Windows Communication Foundation.

  2. Descargue Utilidades de servicio de flujo de trabajo y guárdelo para que las carpetas DuplexWorkflowService y WorkflowServiceUtility se encuentren en la misma carpeta primaria.

  3. Si no desea utilizar los proveedores de persistencia, marque con comentarios la sección <WorkflowRuntime> en los archivos App.config.

  4. Este ejemplo utiliza dos bases de datos de persistencia. El flujo de trabajo del servicio utiliza uno llamado NetFx35Samples_ServiceWorkflowStore, y el cliente utiliza el llamado NetFx35Samples_ClientWorkflowStore. Puede crear estos almacenes en SQL Server o SQL Server Express. Las cadenas de conexión actuales situadas en los archivos App.config suponen que está utilizando SQL Server Express. Si crea los almacenes en SQL Server, asegúrese de cambiar las cadenas de conexión en los archivos App.config.

  5. Cuando el host del cliente y el host del servicio se están ejecutando, presione Y en la ventana de la consola para procesar los elementos de trabajo. Puede enviar varios elementos de trabajo para procesar. Si cierra y reinicia el cliente, se reanuda desde donde acabó.

  6. Para probar la naturaleza duradera de los servicios, cerrar el cliente y las aplicaciones de servicio, y, a continuación, reiniciar primero la aplicación cliente seguida por la aplicación de servicio. El objetivo de esto es secuenciar, porque en cuanto el flujo de trabajo del servicio se esté ejecutando, intenta devolver los mensajes al cliente; si el cliente no está disponible, recibe una excepción.

  7. En el cliente, el contexto se almacena en el archivo Client.ctx. El archivo está almacenado en el directorio \bin de su ejemplo. Al volver a abrir el cliente, compruebe si el archivo está presente. Si lo está, aplica el contexto almacenado al canal que se crea. Si el servicio del flujo de trabajo ha finalizado y abre el cliente con el archivo Client.ctx aún en su directorio \bin, éste intenta aplicar el contexto al canal. Esto produce un error porque la instancia de flujo de trabajo con la que desea comunicarse no está allí. Elimine el archivo y vuelva a intentarlo.

Footer image

Copyright © 2007 Microsoft Corporation. Reservados todos los derechos.