Объединяя этот пост в блоге и просматривая онлайн-документы, я реализовал Инспектор сообщений, пользовательское поведение и применил его к своему сервису.
Поскольку мой сервис дуплексный, для захвата всехтрафик, мне нужно добавить инспекторы сообщений как в конечную точку на стороне сервера, так и во время выполнения клиента обратного вызова.Эта точка, по-видимому, отсутствует во многих онлайн-примерах.
Пользовательский инспектор
public class EndPointMessageInspector : IDispatchMessageInspector, IClientMessageInspector
{
static long _bytesWritten = 0;
static long _bytesRead = 0;
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
request = buffer.CreateMessage();
_bytesRead += buffer.CreateMessage().ToString().Length;
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
if (reply != null)
{
MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);
reply = buffer.CreateMessage();
_bytesWritten += buffer.CreateMessage().ToString().Length;
}
}
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
// No replies expected from Duplex call backs
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
{
if (request != null)
{
MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
request = buffer.CreateMessage();
_bytesWritten += buffer.CreateMessage().ToString().Length;
}
return null;
}
}
Поведение пользовательской службы
[AttributeUsage(AttributeTargets.Class)]
public class GatherThroughputBehaviour : Attribute, IServiceBehavior, IEndpointBehavior
{
#region IServiceBehavior Members
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++)
{
ChannelDispatcher channelDispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher;
if (channelDispatcher != null)
{
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
{
EndPointMessageInspector inspector = new EndPointMessageInspector();
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
}
}
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
#endregion
#region IEndpointBehavior Members
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new EndPointMessageInspector());
endpointDispatcher.DispatchRuntime.CallbackClientRuntime.MessageInspectors.Add(new EndPointMessageInspector());
}
public void Validate(ServiceEndpoint endpoint)
{
return;
}
#endregion
}
Примените Поведение к моему Служению
[GatherThroughputBehaviour]
public class TunnelServer : IMyContract
{
...
}