on service:
using System;
using System.Diagnostics;
using System.IO;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Xml;
namespace Service1
{
class Interceptor : IEndpointBehavior, IDispatchMessageInspector
{
private object o = new object();
private int lineNo;
private class Info
{
public int Row { get; set; }
public int Col { get; set; }
public Stopwatch Stopwatch { get; set; }
}
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
}
public void Validate(ServiceEndpoint endpoint)
{
}
public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
lock (o)
{
Console.Write("{0} Received Request...", ++lineNo);
var info = new Info { Row = Console.CursorTop, Col = Console.CursorLeft, Stopwatch = Stopwatch.StartNew() };
Console.WriteLine();
return info;
}
}
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
var buffer = reply.CreateBufferedCopy(int.MaxValue);
reply = buffer.CreateMessage();
var size = CalculateSize(buffer.CreateMessage());
buffer.Close();
lock (o)
{
var x = correlationState as Info;
var top = Console.CursorTop;
var left = Console.CursorLeft;
Console.CursorTop = x.Row;
Console.CursorLeft = x.Col;
Console.Write("Sending Response {0:N} bytes in {1:0.0} sec", size, x.Stopwatch.Elapsed.TotalSeconds);
Console.CursorTop = top;
Console.CursorLeft = left;
}
}
private static long CalculateSize(Message message)
{
using(var ms = new MemoryStream())
{
using (var writer = XmlDictionaryWriter.CreateBinaryWriter(ms))
{
message.WriteMessage(writer);
return ms.Position;
}
}
}
}
}
service host:
using (var host = new ServiceHost(typeof(Service1)))
{
host.Opening += host_Opening;
host.Opened += host_Opened;
foreach (var endpoint in host.Description.Endpoints)
{
endpoint.EndpointBehaviors.Add(interceptor);
Console.WriteLine("opening {0}...", endpoint.Address);
}
client:
using System;
using System.Diagnostics;
using System.IO;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Threading;
using System.Xml;
namespace Client1
{
class Interceptor : IEndpointBehavior, IClientMessageInspector
{
private object o = new object();
private int lineNo;
private class Info
{
public int Row { get; set; }
public int Col { get; set; }
public Stopwatch Stopwatch { get; set; }
}
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(this);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
var buffer = reply.CreateBufferedCopy(int.MaxValue);
reply = buffer.CreateMessage();
var size = CalculateSize(buffer.CreateMessage());
buffer.Close();
lock (o)
{
var x = correlationState as Info;
var top = Console.CursorTop;
var left = Console.CursorLeft;
Console.CursorTop = x.Row;
Console.CursorLeft = x.Col;
Console.Write("Received Response {0:N} bytes in {1:0.0} sec", size, x.Stopwatch.Elapsed.TotalSeconds);
Console.CursorTop = top;
Console.CursorLeft = left;
}
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
lock (o)
{
Console.Write("[{0}] {1} Sending Request...", Thread.CurrentThread.ManagedThreadId, ++lineNo);
var info = new Info { Row = Console.CursorTop, Col = Console.CursorLeft, Stopwatch = Stopwatch.StartNew() };
Console.WriteLine();
return info;
}
}
private static long CalculateSize(Message message)
{
using (var ms = new MemoryStream())
{
using (var writer = XmlDictionaryWriter.CreateBinaryWriter(ms))
{
message.WriteMessage(writer);
return ms.Position;
}
}
}
}
}
client:
svc.Endpoint.EndpointBehaviors.Add(interceptor);
I have to say for a long time I couldn’t figure out how to tidy the formatting of my code. Finally I discovered how to do it: http://en.support.wordpress.com/code/posting-source-code/