Calculating WCF message size

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/

This entry was posted in Software. Bookmark the permalink.

Leave a comment