Разработка распределенных приложений в Microsoft.NET Framework


Использование очередей сообщений MSMQ в NET Framework - часть 4


Для ответа на сообщение серверу следует использовать очередь, указанную в поле ResponseQueue посылаемого сообщения.

public void Send(RequestType request) { // создание нового сообщения Message message = new Message(request, requestFormatter); message.ResponseQueue = queueReceive; // использование восстаналиваемых сообщений message.Recoverable = Recoverable; // послать сообщение; поскольку транзакция состоит из // единственной операции, вместо объекта-транзакции используется // значение MessageQueueTransactionType.Single queueSend.Send(message, MessageQueueTransactionType.Single); // поле message.Id устанавливается после посылки сообщения; // идентификатор сообщения связывается c отосланным запросом // в списке необслуженных запросов messages.Add(message.Id, request); }

Обработчик события очереди PeekComplete использует внутренние транзакции MSMQ. В одну транзакцию входит операция чтения ответа из очереди и последующий вызов события ProcessAnswer. Если в ходе обработки события возникло исключение, ответ сервера останется в очереди ответов. Иначе сообщение удаляется из поддерживаемого клиентом списка невыполненных запросов.

public void OnPeek(Object source, PeekCompletedEventArgs asyncResult) { // создание внутренней транзакции MSMQ MessageQueueTransaction transaction = new MessageQueueTransaction(); // начало транзакции transaction.Begin(); try { // прекратить ожидание сообщений в очереди queueReceive.EndPeek(asyncResult.AsyncResult); // получить сообщение из очереди в рамках транзакции Message message = queueReceive.Receive(transaction); // в поле CorrelationId должен быть идентификатор сообщения // с исходным запросом String messageId = message.CorrelationId; // есть ли такое сообщение в списке невыполненных запросов? if (messages.ContainsKey(messageId)) { if (message.Body is AnswerType) { // преобразовать тело сообщения к типу ответа // и вызвать событие по его обработке AnswerType answer = (AnswerType) message.Body; ProcessAnswer(this, messages[messageId], answer); }; messages.Remove(messageId); } // продолжить ожидать сообщения BeginReceive(); // успешное завершение транзакции transaction.Commit(); } catch (Exception e) { // отмена транзакции transaction.Abort(); throw e; } } } Листинг 5.2.

MSMQServer – класс общего вида, принимающий через MSMQ запросы и посылающий ответы на них.




Начало  Назад  Вперед