我终于设法在.net 4.0中的WCF中使用NetTcpBinding进行压缩。但这对我来说似乎很讨厌,所以也许别人有更好的主意。
一些一般信息:
我的第一种方法是在客户端和服务器端实现一个消息调度程序,它执行压缩:
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)。但是在局域网和广域网上,性能会有显着提高(最多几秒)。
那你怎么想: