Click here to Skip to main content
12,953,937 members (43,551 online)
Click here to Skip to main content


30 bookmarked
Posted 12 Nov 2008

Remoting Compression Channel Sink

, 12 Nov 2008 CPOL
An article explaining a Remoting extensible channel sink architecture and an implementation of the compression channel sink.
using System.IO;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Messaging;

namespace Util
    internal class CompressionServerChannelSink : BaseChannelSinkWithProperties, IServerChannelSink
        // The next sink in the sink chain.
        private readonly IServerChannelSink _next = null;

        // The compression threshold.
        private readonly int _compressionThreshold;

        #region IServerChannelSink Members

        /// <summary>
        /// Constructor with properties.
        /// </summary>
        /// <param name="nextSink">Next sink.</param>
        /// <param name="compressionThreshold">Compression threshold. If 0, compression is disabled globally.</param>
        public CompressionServerChannelSink(
            IServerChannelSink nextSink,
            int compressionThreshold)
            // Set the next sink.
            _next = nextSink;
            // Set the compression threshold.
            _compressionThreshold = compressionThreshold;

        public void AsyncProcessResponse(
            IServerResponseChannelSinkStack sinkStack,
            object state,
            IMessage msg,
            ITransportHeaders headers,
            Stream stream)
            // Send the response to the client.
            sinkStack.AsyncProcessResponse(msg, headers, stream);

        public Stream GetResponseStream(
            IServerResponseChannelSinkStack sinkStack,
            object state,
            IMessage msg,
            ITransportHeaders headers)
            // Always return null
            return null;

        public IServerChannelSink NextChannelSink
            get { return _next; }

        /// <summary>
        /// Returns true if the message contains the compression exempt parameters, marked as
        /// NonCompressible
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static bool IsCompressionExempt(IMessage msg)
            bool compressionExempt = false;
            if (msg != null && msg.Properties.Contains("__Return"))
                object obj = msg.Properties["__Return"];
                if (obj.GetType().IsDefined(typeof (NonCompressible), false))
                    compressionExempt = true;
                if (obj is ICompressible)
                    if (((ICompressible)obj).PerformCompression() == false)
                        compressionExempt = true;
            return compressionExempt;

        public ServerProcessing ProcessMessage(
            IServerChannelSinkStack sinkStack,
            IMessage requestMsg,
            ITransportHeaders requestHeaders,
            Stream requestStream,
            out IMessage responseMsg,
            out ITransportHeaders responseHeaders,
            out Stream responseStream)
            // Push this onto the sink stack
            sinkStack.Push(this, null);

            // If the request has the compression flag, decompress the stream.
            if (requestHeaders[CommonHeaders.CompressionEnabled] != null)
                // Process the message and decompress it.
                requestStream = CompressHelper.Decompress(requestStream);

            // Retrieve the response from the server.
            ServerProcessing processingResult = _next.ProcessMessage(sinkStack, requestMsg, requestHeaders,
                                                    requestStream, out responseMsg, out responseHeaders,
                                                    out responseStream);

            // If the response stream length is greater than the threshold,
            // message is not exempt from compression, and client supports compression,
            // compress the stream.
            if (processingResult == ServerProcessing.Complete
                && _compressionThreshold > 0
                && responseStream.Length > _compressionThreshold
                && !IsCompressionExempt(responseMsg)
                && requestHeaders[CommonHeaders.CompressionSupported] != null)
                // Process the message and compress it.
                responseStream = CompressHelper.Compress(responseStream);

                // Send the compression flag to the client.
                responseHeaders[CommonHeaders.CompressionEnabled] = true;

            // Take off the stack and return the result.
            return processingResult;


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

United States United States
Alexander Schmidt. I'm a software developer, who is working primarily with Microsoft technologies including Microsoft .NET. I'm also interested in optimization problems and software engineering in general. You can visit my blog at

You may also be interested in...

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170525.1 | Last Updated 13 Nov 2008
Article Copyright 2008 by aschmidt
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid