Проблема реализации собственной разработки надежной службы WCF для SilverLight (basicHttpBinding)

Я пытаюсь реализовать очень простую надежную систему обработки состояния сообщений, чтобы обеспечить повышенную надежность связи между сервером Silverlight и WCF.

Я пошел по пути введения пользовательского заголовка сообщения в запрос SOAP, который содержит увеличивающееся целое число в качестве идентификатора сообщения. Идея состоит в том, что когда я получаю запрос на сервере WCF, я хочу проверить идентификатор сообщения. Если идентификатор > последнего идентификатора, то я просто выполняю запрос и ПОСЛЕ запроса я кэширую копию результата вместе с новым идентификатором.

Если идентификатор == lastID, я предполагаю, что клиент никогда не получал мое сообщение, и я хочу просто вернуть кешированный объект ответа вместо повторной обработки запроса. Я написал объект MessageInspector Behavior, который я вставляю в поведение конечной точки WCF. Этот объект реализует IDispatchMessageInspector, который имеет 2 метода:

object IDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel, InstanceContext instanceContext)
{
    // Get the incoming message headers and get the messageId
    var idx = request.Headers.FindHeader("ClientRequestId", "");
    if (idx >= 0)
    {
        var requestHeader = request.Headers[idx];
        int requestId = 0;
        if (Int32.TryParse(requestHeader.ToString(), out requestId))
        {
            int lastRequest = myCache.GetLastId();
            if (requestId <= lastRequest)
            {
                // @TODO - Send back the saved message
                var reply = myCache.GetLastResponse();
                if (reply != null)
                {
                    /// ERK -- > Woops, how do I override the service
                    /// and make the reply here?
                }
            }
            myCache.SetLastId(requestId);
        }
    }
    return null;
}

void IDispatchMessageInspector.BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
    var requestId = myCache.GetLastId();
    if (requestId > 0)
    {
        myCache.SetLastResponse(reply);
    }
}

Что ж, проблема, с которой я столкнулся, должна быть очевидной... Возвращаемое значение AfterReceiveRequest (объект) — это значение, переданное в BeforeSendReply как "correlatedState". НЕ, как я изначально предполагал, новое возвращаемое значение для запроса. Вопрос в том, могу ли я остановить обработку сообщения службой в этом месте и вернуть «кэшированный» ответ?

На самом деле лучшая версия этого вопроса: является ли это подходящим местом «внедрения» для обработки кэширования и отслеживания ответов? Если нет, то где будет «одобренная ms» или лучший способ выполнить отслеживание и восстановление этого запроса?

благодаря.

-Джефф


person Jeff    schedule 05.07.2009    source источник


Ответы (2)


я думаю, что вы пытаетесь немного заново изобрести велосипед здесь. WCF имеет надежный обмен сообщениями, который уже разработан для обеспечения доставки сообщений. Я бы попробовал это, если только вы не хотите использовать его по определенной причине?

person Tanner    schedule 06.07.2009
comment
Да, но, насколько мне известно, надежный обмен сообщениями WCF НЕ доступен в Silverlight. Silverlight реализует только базовую привязку HttpBinding, которая, насколько я читал, не поддерживает надежный обмен сообщениями. - person Jeff; 06.07.2009

После долгих проб и невзгод я нашел решение своей проблемы, которое если и не элегантно, то функционально.

Чтобы обойти вызов конечной точки службы, когда я обнаруживаю повторяющийся запрос на службу, я просто создаю FaultException. Затем в методе BeforeSendReply я проверяю, есть ли replay.IsFault, а затем, является ли ошибка конкретным кодом ошибки, который я указал в AfterReceiveRequest. Если это так, я возвращаю кэшированную копию ответа на сообщение. Механизм FaultException — это то, что мне нужно использовать, чтобы обойти вызов службы.

Если кому-то нужен полный рабочий код для этого решения, оставьте заметку здесь, и я опубликую свой окончательный код после завершения окончательной отладки и модульного тестирования.

-Джефф

person Jeff    schedule 07.07.2009