3.29.2014

Request–Response con el Windows Service Bus

El bus en su versión de Windows no tiene “relay service” disponible como si sucede en el bus de servicios de Azure, por lo tanto solo se soportan transacciones asíncronas. En este sentido solo tenemos como opción utilizar colas o tópicos ya que no podemos conectar servicios creados en WCF y hosteados en el IIS al Windows Service Bus para que sean atendidos en un patrón solicitud y respuesta.

Sin embargo, como bien lo definimos en el titulo de este post, si existe una forma de crear solitudes de dos vías en el Windows Service Bus y es utilizando correlación, sesiones y colas.

El Cliente

El primer paso es crear el cliente del servicio es decir, el que envía la solicitud. Para esto primero creamos variables para tener acceso a la cola de envío y a la cola de respuesta.

  1: var _requestQueue = QueueClient.CreateFromConnectionString(ServiceBusEndpoint, "RequestQueue");
  2: var _responseQueue = QueueClient.CreateFromConnectionString(ServiceBusEndpoint, "ResponseQueue", ReceiveMode.ReceiveAndDelete);

Luego creamos un while para presentar la consola hasta que el cliente digite una tecla que sea diferente a “n” o “N”, en cuyo caso el cliente nos estará diciendo que no quiere enviar mas mensajes.


Dentro de este While vamos a crear un Id de sesión único utilizando un Guid de sistema y procedemos a solicitar el numero de cliente que el usuario desea ingresar; por ultimo establecemos la sesión utilizando el id de sesión único que acabamos de generar.

  1: var _replyToSessionId = Guid.NewGuid().ToString();
  2: Console.WriteLine("Digite el numero de cliente: ");
  3: string _numeroDeCliente = Console.ReadLine();
  4: var _messageSession = _responseQueue.AcceptMessageSession(_replyToSessionId);
  5: 

El siguiente paso es crear el mensaje que vamos a enviar. Este contendrá el numero de cliente ingresado por el cliente, pero además tendrá el valor de la sesión y la propiedad ReplyToSessionId establecidos por el Id de sesión único creado anteriormente con el Guid del sistema. Después de esto enviamos el mensaje.

  1: var _mensaje = new BrokeredMessage(_numeroDeCliente)
  2: {
  3:     SessionId = _replyToSessionId,
  4:     ReplyToSessionId = _replyToSessionId,
  5:     MessageId = DateTime.Now.ToBinary().ToString()
  6: };
  7: _requestQueue.Send( _mensaje );
  8: Console.ForegroundColor = ConsoleColor.Cyan;
  9: Console.WriteLine("Mensaje enviado. Id Mensaje = " + _mensaje.MessageId);

Por ultimo esperamos la respuesta del mensaje y lo desplegamos en la consola.

  1: Console.ForegroundColor = ConsoleColor.Cyan;
  2: Console.WriteLine("Mensaje enviado. Id Mensaje = " + _mensaje.MessageId);
  3: 
  4: var _responseMessage = _messageSession.Receive(TimeSpan.FromSeconds(20));
  5: if (_responseMessage != null)
  6: {
  7:     Console.ForegroundColor = ConsoleColor.Green;
  8:     Console.WriteLine("Mensaje recibido: {0}. El nombre del cliente es {1}", _responseMessage.MessageId, _responseMessage.GetBody<string>());
  9: }

El Servidor


Seguidamente creamos el servidor que va a procesar la solicitud enviada por el cliente y va a responder a la instancia del cliente. El primer paso es crear dos colas, una hacia donde se envía la solicitud, y otra hacia donde se envía y se busca la respuesta a la solicitud.

  1:         private QueueClient _requestQueue;
  2:         private QueueClient _responseQueue;

Luego procedemos a crear el método que va a procesar la respuesta. Inicialmente se crea una sesión, luego de esto hacemos un ciclo “while” en donde nos quedamos esperando hasta que llegue un mensaje a la cola de recibo. Como se puede ver en el segundo while, nos quedamos esperando hasta que la variable _messageSession sea diferente de nulo; el estado de esta variable cambiara cuando la operación de solicitud de mensaje devuelva un mensaje recibido en la cola de solicitud _requestQueue.

  1: while (true)
  2: {
  3:   MessageSession _messageSession = null;
  4:   while (_messageSession == null)
  5:   {
  6:       try
  7:       {
  8:           Console.ForegroundColor = ConsoleColor.DarkMagenta;
  9:           Console.WriteLine("Aceptando la sesion del mensaje");
 10:           _messageSession = _requestQueue.AcceptMessageSession();
 11:           Console.WriteLine("Sesion aceptada");
 12:       }
 13:       catch (TimeoutException _e)
 14:       {
 15:           Trace.WriteLine(_e.ToString());
 16:           throw;
 17:       }
 18:   }


Una vez recibido el mensaje procedemos a procesarlo. El primer paso es extraerlo de la cola para que la instancia del mensaje desaparezca de los mensajes a procesar, esto se logra con la operación MessageSession.Receive. Seguidamente obtenemos el contenido del mensaje con la operacion GetBody y procedemos a imprimir lo recibido. Seguidamente procedemos a crear el mensaje de respuesta, para esto creamos un nuevo mensaje – BrokeredMessage –, le agregamos el nuevo contenido el cual es el mismo del anterior pero con el string “el nombre del cliente <mensaje anterior> es XYZ”. Este nuevo mensaje se responde con una particularidad, la variable SessionId es el valor de la variable ReplyToSessionId y el Id del mensaje sera el mismo que el Id del mensaje recibido, para lo cual usamos la propiedad MessageId de ambos mensajes.

  1:  Console.ForegroundColor = ConsoleColor.Yellow;
  2:     Console.WriteLine("Recibiendo mensajes de la session {0} ", _messageSession.SessionId);
  3:     Console.ForegroundColor = ConsoleColor.Green;
  4:     var _message = _messageSession.Receive(TimeSpan.FromSeconds(5));
  5:     if (_message != null)
  6:     {
  7:         var _numeroDeCliente = _message.GetBody<string>();
  8: 
  9:         Console.WriteLine("Cliente numero: {0}", _numeroDeCliente);
 10: 
 11:         var _nombreCliente = string.Format("El nombre del cliente : {0} es XYZ", _numeroDeCliente);
 12: 
 13:         var _responseMessage = new BrokeredMessage(_nombreCliente)
 14:         {
 15:             SessionId = _message.ReplyToSessionId,
 16:             MessageId = _message.MessageId
 17:         };
 18: 
 19:         _responseQueue.Send(_responseMessage);
 20:     } //fin del if
 21: } //fin de while

Para hacer la prueba primero ejecutamos el servidor que se queda esperando por mensajes.
image

Luego iniciamos el cliente que nos solicita la información del cliente a enviar.
image

Luego digitamos los datos del cliente y podemos ver que el servidor recibe la respuesta de forma inmediata. Al mismo tiempo nos despliega los datos digitados del cliente y procede a contestar.
image



En la siguiente pantalla vemos que el cliente envió ABC y que recibió la respuesta por parte del servidor con el mensaje de texto agregado de vuelta.


image


Etiquetas de Technorati:

No hay comentarios: