/// <summary> /// Serialize the message. /// </summary> /// <param name="message">the message</param> /// <returns>the byte array which is serialized from the message</returns> public static byte[] Serialize(Message message) { using (MemoryStream stream = new MemoryStream()) { var formatter = new BinaryFormatter(); using (AzureQueueMessageItem item = new AzureQueueMessageItem(message)) { formatter.Serialize(stream, item); } return(stream.ToArray()); } }
/// <summary> /// Convert a cloud queue message to wcf message, may need to access /// blob to get large message. /// </summary> /// <param name="message">queue message</param> /// <returns>wcf message</returns> public Message GetWcfMessageFromQueueMessage(CloudQueueMessage message) { Message wcfMessage = AzureQueueMessageItem.Deserialize(message.AsBytes); if (wcfMessage.Headers.FindHeader(Constant.MessageHeaderBlob, Constant.HpcHeaderNS) > 0) { using (wcfMessage) { byte[] data = this.DownloadBlob(wcfMessage.Headers.MessageId); return(AzureQueueMessageItem.Deserialize(data)); } } else { return(wcfMessage); } }
/// <summary> /// Async method for add message. If the message size hits limit, store /// it in blob and add a referral message in queue. /// </summary> /// <param name="messageData">raw data of message</param> /// <param name="messageId">wcf message Id</param> /// <param name="callback">callback method</param> /// <param name="state">state object</param> /// <returns>async state</returns> public IAsyncResult BeginAddMessage(byte[] messageData, UniqueId messageId, AsyncCallback callback, ReliableQueueClient.ReliableState state) { CloudQueueMessage message = new CloudQueueMessage(messageData); try { if (messageData.Length <= MessageSizeBoundary) { message = new CloudQueueMessage(messageData); return(this.ReliableQueue.BeginAddMessage(message, callback, state)); } } catch (ArgumentException e) { // according to the test, when payload is <= 48KB, it can fit // in a queue message. otherwise, ArgumentException occurs. but // there is no doc about this. so catch ArgumentException here, // and store message to blob below. SessionBase.TraceSource.TraceEvent(TraceEventType.Warning, 0, "AzureStorageClient, BeginAddMessage, BeginAddMessage failed, {0}", e); } catch (Exception ex) { SessionBase.TraceSource.TraceEvent(TraceEventType.Error, 0, "AzureStorageClient, BeginAddMessage, BeginAddMessage failed, {0}", ex); throw; } SessionBase.TraceSource.TraceInformation("AzureStorageClient, BeginAddMessage, Upload message {0} to storage blob.", messageId); this.UploadBlob(messageData, messageId); // Store a referral message in Azure queue with the same message Id // as the original message. It redirects proxy to get real message // from the blob. Message referralMessage = Message.CreateMessage(MessageVersion.Default, string.Empty); referralMessage.Headers.MessageId = messageId; referralMessage.Headers.Add( MessageHeader.CreateHeader(Constant.MessageHeaderBlob, Constant.HpcHeaderNS, string.Empty)); message = new CloudQueueMessage(AzureQueueMessageItem.Serialize(referralMessage)); return(this.ReliableQueue.BeginAddMessage(message, callback, state)); }
/// <summary> /// Async Pattern. Callback of BeginProcessMessage method. /// </summary> /// <param name="state">state object</param> private void InternalBeginAddRequest(object state) { Message requestMessage = null; SessionBase.TraceSource.TraceInformation( SoaHelper.CreateTraceMessage( "MessageSender.Worker", "InternalBeginAddRequest", "Request queue length is {0}.", this.requestMessages.Count)); try { if (!this.requestMessages.TryDequeue(out requestMessage)) { SessionBase.TraceSource.TraceInformation( SoaHelper.CreateTraceMessage( "MessageSender.Worker", "InternalBeginAddRequest", "Local response cache is empty.")); } } catch (Exception e) { SessionBase.TraceSource.TraceInformation( SoaHelper.CreateTraceMessage( "MessageSender.Worker", "InternalBeginAddRequest", string.Format("Failed to get response from local cache, {0}", e))); } if (requestMessage == null) { SessionBase.TraceSource.TraceInformation( SoaHelper.CreateTraceMessage( "MessageSender.Worker", "InternalBeginAddRequest", string.Format("Get null request from local cache, trigger the time to wait"))); this.TriggerTimer(); return; } try { UniqueId messageId = SoaHelper.GetMessageId(requestMessage); if (messageId == null) { messageId = new UniqueId(); } ReliableQueueClient.ReliableState reliableState = new ReliableQueueClient.ReliableState(requestMessage, messageId); byte[] messageData; using (requestMessage) { messageData = AzureQueueMessageItem.Serialize(requestMessage); } this.waitHandler.Reset(); this.requestStorageClient.BeginAddMessage(messageData, messageId, this.AddMessageCallback, reliableState); } catch (Exception e) { this.waitHandler.Set(); SessionBase.TraceSource.TraceInformation( SoaHelper.CreateTraceMessage( "MessageSender.Worker", "InternalBeginAddRequest", "Failed to add response message, {0}", e)); this.TriggerTimer(); } }