代码之家  ›  专栏  ›  技术社区  ›  yogi

使用IDispatchMessageInspector记录WCF服务

  •  1
  • yogi  · 技术社区  · 12 年前

    我正在尝试记录请求&对&从我的WCF服务。到目前为止,我所做的是:

    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 必须同步工作,以便 发送前回复 将更新正确的记录。我想到的情况是服务同时被多个客户呼叫,问题是:

    • 不会 lastLogId 搞砸了,在多人之间混来混去 请求&响应?
    • 此日志记录是否会在 发送前回复 会起作用的 多个客户端同时调用服务是否正常?如果是 那么请给我一个解释,让我放心,如果没有的话 请提供更好的解决方案。
    2 回复  |  直到 12 年前
        1
  •  5
  •   ErnieL    12 年前

    我同意@Schneiders解决方案使用WCF日志记录满足您的要求。

    然而,要回答您的问题:

    在BeforeSendReply中特别更新此日志是否可以正常工作 多个客户端同时调用服务?

    不,不会的。的实例 IDispatchMessageInspector 在通话中共享。

    不使用成员财产,而是通过 correlationState 在…上 IDispatchMessageInspector .无论什么物体 AfterReceiveRequest() 返回将作为 相关状态 到 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;
       }
    }
    
        2
  •  1
  •   Jack Ukleja    12 年前

    首先:WCF具有内置的能力 log the requests & responses 因此,在您推出自己的解决方案之前,可能值得对此进行调查。

    对于您的问题,通常您将IDispatchMessageInspector应用为服务或端点行为,并挂接ApplyDispatchBehavior。在那里,您可能正在创建一个新的OutputMessageInspector,并将其添加到DispatchRuntime.MessageInspectors集合中。

    创建服务或端点时,行为只应用一次,因此您可以推断只有一个DispatchRuntime,并且您只创建一个MessageInspector,因此它将在所有请求/线程之间共享。

    在这种情况下,OutputMessageInspector需要“线程安全”。若你们把状态保存在那个里,你们就需要同步对它的访问,这样它就不会被打乱。

    推荐文章