2014-09-12 3 views
0

Я пытаюсь зарегистрировать запросы & ответов на & из моей службы WCF. То, что я сделал до сих пор:Журналирование службы WCF с IDispatchMessageInspector

public class OutputMessageInspector : IDispatchMessageInspector 
{ 
    int lastLogId; 

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
    { 
     // Parse request & read required information 
     // Insert request data into log tables 
     // Set lastLogId to the id created above 
    } 

    public void BeforeSendReply(ref Message reply, object correlationState) 
    { 
     // Parse reply 
     // Using lastLogId update the response column in database table 
    } 
} 

Все работает нормально, но у меня есть одна забота:

AfterReceiveRequest и BeforeSendReply должен работать в синхронизации с тем, что BeforeSendReply будет обновлять правильную запись. Случае я имею в виду службы вызывался от нескольких клиентов в то же время, вопрос:

  • Не было lastLogId получить перепутались и перемешиваются между несколькими запросов & ответы?
  • Будет ли этот журнал специально обновлен на BeforeSendReply будет работать штраф с несколькими клиентами, вызывающими службу в одно и то же время? Если да , то, пожалуйста, дайте мне объяснение, чтобы заверить мой разум, если нет, то , пожалуйста, предложите лучшее решение.

ответ

4

Я согласен с решением @Schneiders использовать использование WCF для ваших требований.

Однако, чтобы ответить на ваш вопрос:

ли это протоколирование специально обновлять на BeforeSendReply будет работать нормально с несколькими клиентами вызова службы в то же время?

Нет, это не будет. Экземпляры IDispatchMessageInspector разделяются между вызовами.

Вместо использования свойств членов, конкретные данные вызова поддерживаются через correlationState по адресу IDispatchMessageInspector. Каким бы ни был объект AfterReceiveRequest(), данные будут переданы как correlationState в BeforeSendReply().

Другими словами что-то, как это должно работать:

public class OutputMessageInspector : IDispatchMessageInspector 
{ 
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
    { 
     // Parse request & read required information 
     // Insert request data into log tables 
     // Set lastLogId to the id created above 
     return lastLogId 
    } 

    public void BeforeSendReply(ref Message reply, object correlationState) 
    { 
     // Parse reply 
     int lastLogId = (int)correlationState; 
    } 
} 
+0

Хорошо, я получил это благодаря :) – yogi

1

Во-первых: WCF имеет встроенную возможность log the requests & responses так что может быть стоит исследовать, что, прежде чем свернуть собственное решение.

Что касается вашей проблемы, обычно вы применяете IDispatchMessageInspector как поведение службы или конечной точки, подключая приложение ApplyDispatchBehavior. Там вы, вероятно, создаете новый OutputMessageInspector и добавляете его в коллекцию DispatchRuntime.MessageInspectors.

Поведение применяется только один раз, когда создается сервис или конечная точка, поэтому вы можете сделать вывод, что существует только одно DispatchRuntime, и вы создаете только один MessageInspector, поэтому он будет использоваться для всех запросов/потоков.

В этом случае ваш OutputMessageInspector должен быть «потокобезопасным». Если вы удерживаете состояние там, вам нужно будет синхронизировать доступ к нему, чтобы он не скремблировался.

+0

на самом деле я не только вход запрос/ответ, я лесозаготовки больше вещей, как параметры аутентификации после разбора запроса XML и IP реквестера. – yogi