Buffers de Mensajes

Un buffer de mensajes puede describirse como una caché temporal dónde los mensajes pueden almacenarse por un periodo corto de tiempo, hasta que éstos son leídos.

Los buffers de mensajes son especialmente útiles cuando no es posible utilizar algunos de los endpoints disponibles en Service Bus para comunicar un cliente con un servidor; por ejemplo, cuando una de las partes de la comunicación no se encuentra un sistema operativo Windows o está implementado en otra tecnología como puede ser Java.

El buffer de mensajes puede ser accedido desde cualquier tecnología empleando el protocolo HTTP y no requiere disponer del SDK de Windows Azure. El buffer de mensajes expone una serie de operaciones por REST para permitir crear mensajes, enviarlos y recibirlos.

El protocolo de comunicación con el buffer de mensajes emplea Access Control para realizar el proceso de autenticación y autorización, empleando el mecanismo de Simple Web Token (SWT) como mecanismo de seguridad. El protocolo permite los verbos POST/PUT, PUT, DELETE y GET.

A continuación se muestra un ejemplo  de como emplear el protocolo HTTP REST para crear un buffer de mensajes y enviar y recibir mensajes de él.

// Prompt the user for the service namespace and issuer key. 
Console.Write("Please enter your Service Namespace: ");
string serviceNamespace = Console.ReadLine();
Console.Write("Please enter the key for the 'owner' issuer: ");
string ownerKey = Console.ReadLine();
// Create a GUID for the buffer name.
string bufferName = Guid.NewGuid().ToString("N");
// Construct the message buffer URI.
string messageBufferLocation = string.Format("http://
{0}.servicebus.windows.net/{1}", serviceNamespace, bufferName);
// Get the AC token WebClient
client = new WebClient();
client.BaseAddress = string.Format ("https://{0}-sb.accesscontrol
.windows.net/", serviceNamespace);
NameValueCollection values = new NameValueCollection();
values.Add("wrap_name", "owner");
values.Add("wrap_password", ownerKey);
values.Add(" wrap_scope", messageBufferLocation);
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST",values);
string response = Encoding.UTF8.GetString(responseBytes);
string token = Uri. UnescapeDataString( response.Split('&').Single
(value => value.StartsWith("wrap_access_token=",
StringComparison.OrdinalIgnoreCase)) .Split('=')[1]);
// Create the auth header from the token
string authHeaderValue =string.Format("WRAP access_token=\"{0}\"", token);
// Create the message buffer policy.
string policy = "<entry xmlns=\ "http://www.w3.org/2005/Atom\">"
+ "<content type=\"text/xml\">" + "<MessageBufferPolicy xmlns=\
"https://schemas.microsoft.com/netservices/2009
/05/servicebus/connect\"/>" + "</content>" + "</entry>";
// Create a message buffer.
client.BaseAddress = string.Format("https://{0}.servicebus.
windows.net/{1}/", serviceNamespace, bufferName);
client.Headers[HttpRequestHeader.ContentType] = "application/atom+xml;
type=entry;charset=utf-8";
client.Headers[ HttpRequestHeader.Authorization] = authHeaderValue;
client.UploadData (String.Empty, PUT", ncoding.UTF8.GetBytes(policy));
Console.WriteLine ("Message buffer was created at '{0}'.",
messageBufferLocation);
// Send a message to the message buffer.
client.Headers[HttpRequestHeader.ContentType] = "text/xml";
client.Headers[HttpRequestHeader.Authorization]= authHeaderValue;
client.UploadData ("messages?timeout=20", "POST",
Encoding.UTF8.GetBytes("<msg1> This is message #1</msg1>"));
Console.WriteLine("Message sent.");
// Retrieve message.
client.Headers[HttpRequestHeader.Authorization] = authHeaderValue;
string payload = Encoding.UTF8.GetString(client.UploadData
("messages/head?timeout=20", "DELETE", new byte[0]));
Console.WriteLine("Retrieved the message '{0}'.", payload);
// Delete the message buffer.
client.Headers[HttpRequestHeader .Authorization] = authHeaderValue;
client.UploadData(String. Empty, "DELETE", new byte[0]);
Console.WriteLine("Message buffer at '{0}' was deleted."
, messageBufferLocation);

Aunque no es necesario disponer del SDK de Windows Azure, éste también provee una serie de funcionalidad que pueden ayudar a simplificar el trabajo con los buffers de mensajes.

En el siguiente ejemplo se muestra como configurar y crear un buffer de mensajes y cómo poder enviar y recibir mensaje de él, todo empleando el SDK de Windows Azure.

string serviceNamespace = "...";
MessageVersion messageVersion = MessageVersion.Soap12WSAddressing10;
string messageAction = "urn:Message";
// Configure credentials.
TransportClientEndpointBehavior behavior = new
TransportClientEndpointBehavior();
behavior.CredentialType = TransportClientCredentialType.SharedSecret;
behavior. Credentials.SharedSecret.IssuerName = "...";
behavior.Credentials.SharedSecret.IssuerSecret = "...";
// Configure buffer policy.
MessageBufferPolicy policy = new MessageBufferPolicy { ExpiresAfter =
TimeSpan.FromMinutes(2.0d), MaxMessageCount = 100 };
// Create message buffer.
string bufferName = "MyBuffer";
Uri bufferLocation = new Uri("https://" + serviceNamespace +
".servicebus.windows.net/services/" + bufferName);
MessageBufferClient client = MessageBufferClient. CreateMessageBuffer
(behavior,bufferLocation, policy, messageVersion);
// Send 10 messages.
for (int i = 0; i < 10; ++i)
{ client.Send(Message.CreateMessage(messageVersion,
messageAction, "Message #" + i));
}
Message message;
string content;
// Retrieve a message (destructive read).
message = client.Retrieve();
content = message.GetBody<string>();
message.Close();
Console.WriteLine("Retrieve message content: {0}", content);
// Retrieve a message (peek/lock).
message = client.PeekLock();
content = message.GetBody<string>();
Console.WriteLine("PeekLock message content: {0}", content);
// Delete previously locked message.
client.DeleteLockedMessage(message);
message.Close();
// If no more messages are retrieved within the ExpiresAfter
// time span, the buffer will automatically be deleted...