[英]WCF service logging with IDispatchMessageInspector
我正在尝试记录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
必须保持同步,以便BeforeSendReply
将更新正确的记录。 我想到的是服务同时从多个客户端调用的问题:
lastLogId
会变得混乱和混乱? BeforeSendReply
专门更新是否适用于同时调用服务的多个客户端? 如果是,请给我一个解释,以确保我的想法。如果不是,请提供一个更好的解决方案。 我同意@Schneiders解决方案使用WCF日志记录来满足您的要求。
但是要回答你的问题:
此日志在BeforeSendReply上进行的专门更新是否适用于同时调用服务的多个客户端?
不,不会。 IDispatchMessageInspector
实例在调用之间共享。
通过使用IDispatchMessageInspector
上的correlationState
支持调用特定的数据,而不是使用成员属性。 无论对象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;
}
}
首先:WCF具有记录请求和响应的内置功能,因此在推出自己的解决方案之前可能值得调查一下。
对于您的问题,通常您将IDispatchMessageInspector作为服务或端点行为应用,因此钩住ApplyDispatchBehavior。 在其中,您可能会创建一个新的OutputMessageInspector并将其添加到DispatchRuntime.MessageInspectors集合中。
行为在创建服务或端点时仅应用一次,因此您可以推断出只有一个DispatchRuntime,并且您仅创建一个MessageInspector,因此它将在所有请求/线程之间共享。
在这种情况下,您的OutputMessageInspector需要是“线程安全的”。 如果您在那里保持状态,则需要同步对其的访问,以免混乱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.