简体   繁体   English

使用IDispatchMessageInspector记录WCF服务

[英]WCF service logging with IDispatchMessageInspector

I'm trying to log the requests & responses to & from my WCF service. 我正在尝试记录WCF服务对&的请求和响应。 What I have done till now is: 到目前为止,我所做的是:

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
   }
}

Everything is working fine but I have one concern: 一切正常,但我有一个担忧:

AfterReceiveRequest and BeforeSendReply has to be working in a sync so that BeforeSendReply will update correct record. AfterReceiveRequestBeforeSendReply必须保持同步,以便BeforeSendReply将更新正确的记录。 The case I have in mind is of Service getting called from multiple clients at the same time, question: 我想到的是服务同时从多个客户端调用的问题:

  • Wouldn't lastLogId get messed up and shuffled among multiple requests & responses? 在多个请求和响应之间, lastLogId会变得混乱和混乱?
  • Would this logging specially update at BeforeSendReply will work fine with multiple clients calling service at the same time? 此日志在BeforeSendReply专门更新是否适用于同时调用服务的多个客户端? If yes then please give me an explanation to assure my mind if no then please provide a better solution to this. 如果是,请给我一个解释,以确保我的想法。如果不是,请提供一个更好的解决方案。

I agree with @Schneiders solution to use WCF logging for your requirements. 我同意@Schneiders解决方案使用WCF日志记录来满足您的要求。

However to answer your question: 但是要回答你的问题:

Would this logging specially update at BeforeSendReply will work fine with multiple clients calling service at the same time? 此日志在BeforeSendReply上进行的专门更新是否适用于同时调用服务的多个客户端?

No it will not. 不,不会。 Instances of the IDispatchMessageInspector are shared across calls. IDispatchMessageInspector实例在调用之间共享。

Instead of using member properties, call specific data is supported through the correlationState on IDispatchMessageInspector . 通过使用IDispatchMessageInspector上的correlationState支持调用特定的数据,而不是使用成员属性。 Whatever object AfterReceiveRequest() returns will be passed as the correlationState to BeforeSendReply() . 无论对象AfterReceiveRequest()返回什么,都将作为correlationState传递给BeforeSendReply()

In other words something like this should work: 换句话说,这样的事情应该起作用:

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;
   }
}

Firstly: WCF has the built in ability to log the requests & responses so it might be worth investigating that before you roll your own solution. 首先:WCF具有记录请求和响应的内置功能,因此在推出自己的解决方案之前可能值得调查一下。

As to your problem, normally you are applying the IDispatchMessageInspector as a service or endpoint behaviour, hooking the ApplyDispatchBehavior. 对于您的问题,通常您将IDispatchMessageInspector作为服务或端点行为应用,因此钩住ApplyDispatchBehavior。 In there you are probably creating a new OutputMessageInspector and adding it to the DispatchRuntime.MessageInspectors collection. 在其中,您可能会创建一个新的OutputMessageInspector并将其添加到DispatchRuntime.MessageInspectors集合中。

Behaviors only get applied once when the service or endpoint is created, so you can infer from that there is only one DispatchRuntime and you are only creating one MessageInspector so it's going to be shared across all requests/threads. 行为在创建服务或端点时仅应用一次,因此您可以推断出只有一个DispatchRuntime,并且您仅创建一个MessageInspector,因此它将在所有请求/线程之间共享。

In which case your OutputMessageInspector needs to be "thread safe". 在这种情况下,您的OutputMessageInspector需要是“线程安全的”。 If you hold state in there you are going to need to synchronize access to it so that it doesn't get scrambled. 如果您在那里保持状态,则需要同步对其的访问,以免混乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM