在.net 4.0中使用NetTcpBinding进行WCF压缩

时间:2014-02-28 09:19:31

标签: c# wcf .net-4.0 compression nettcpbinding

我终于设法在.net 4.0中的WCF中使用NetTcpBinding进行压缩。但这对我来说似乎很讨厌,所以也许别人有更好的主意。

一些一般信息:

  • 我知道这是开箱即用的.net 4.5 - 但我们坚持4.0
  • 我在CustomBinding中找到了几个例子 - 但我们想坚持使用NetTcpBinding,因为二进制enconding(它比文本enconding更快)
  • 我们正在进行代码中的所有配置(服务器地址除外),因此对于客户而言,它只是即插即用,没有机会改变任何东西 - 但有时也很难让一个示例工作(大多数是在配置文件)

我的第一种方法是在客户端和服务器端实现一个消息调度程序,它执行压缩:

http://dotnetlombardia.org/b/tonyexpo/archive/2011/03/09/compressione-in-wcf.aspx

但无论何时我以任何方式更改(或替换)原始邮件,客户端的AfterReceiveReply都从未执行过。 虽然在WCF跟踪中我可以看到客户端收到了消息,甚至向服务器收到的服务器发送了ACK!但是客户端进入了超时状态?!

然后我找到了MessageEncoderFactory以供Microsoft进行压缩:

http://msdn.microsoft.com/en-us/library/ms751458%28v=vs.110%29.aspx

并应用此处提供的错误修复:

http://blogs.msdn.com/b/dmetzgar/archive/2011/03/14/gzipmessageencoder-part-two.aspx

最后我继承了NetTcpBinding并在CreateBindingElements函数中应用了新的消息编码器:

    public class CompressedNetTcpBinding : NetTcpBinding
    {
        MyCompressionMessageEncodingBindingElement compressionEncoding;

        public CompressedNetTcpBinding()
            : base()
        {
            FieldInfo fi = typeof(NetTcpBinding).GetField("encoding", BindingFlags.Instance | BindingFlags.NonPublic);
            BinaryMessageEncodingBindingElement binaryEncoding = (BinaryMessageEncodingBindingElement)fi.GetValue(this);
            compressionEncoding = new MyCompressionMessageEncodingBindingElement(binaryEncoding, CompressionAlgorithm.Deflate);
        }

        /// <summary>
        /// Exchange <see cref="BinaryMessageEncodingBindingElement"/> and use compressed encoding binding element.
        /// </summary>
        /// <returns>binding elements with compressed message binding element</returns>
        public override BindingElementCollection CreateBindingElements()
        {
            BindingElementCollection bec = base.CreateBindingElements();
            BinaryMessageEncodingBindingElement enc = null;
            foreach (BindingElement be in bec)
            {
                if (be is BinaryMessageEncodingBindingElement)
                {
                    enc = (BinaryMessageEncodingBindingElement)be;
                    break;
                }
            }
            bec.Remove(enc);
            bec.Insert(2, compressionEncoding);

            return bec;
        }
    }

我确实将普通的BinaryMessageEncoder转发为压缩编码,因此当我更改NetTcpBinding的任何设置时,例如ReaderQuotas它们被正确应用。

我知道NetTcpBinding中的enconding成员也在私有函数IsBindingElementsMatch中使用,但到目前为止并没有引起任何问题。

在我的本地计算机上,(启动)性能损失是微不足道的(100ms - 250ms)。但是在局域网和广域网上,性能会有显着提高(最多几秒)。

那你怎么想:

  • 这是一种方式吗?
  • 有没有更好的解决方案?

0 个答案:

没有答案