gpt4 book ai didi

c# - 如何计算 WCF 服务器发送到客户端的消息流的大小

转载 作者:太空宇宙 更新时间:2023-11-03 15:27:21 24 4
gpt4 key购买 nike

从服务器端,有时我们会发送非常大的数据,这些数据会超过客户端 NET TCP 绑定(bind)中定义的限制。在这种情况下,我们会在客户端收到通信异常。如果我在客户端增加绑定(bind)参数 MaxReceivedMessageSize 的大小,问题得到解决,但我们不确定 WCF 服务器将向我们发送多少数据,并且它可能再次超过客户端 MaxReceivedMessageSize 中定义的限制。

有什么方法可以让我知道 WCF 服务器要发送给客户端的消息流的实际大小,这样如果大小超过客户端定义的大小,那么在发送之前,我可以修剪服务器端的消息内容达到该限制。

最佳答案

字节流的大小取决于所使用的编码器,不同的编码器产生不同大小的字节流。

我写了一个 MessageInspector,它进行消息/流重写以计算最终字节流的大小。在客户端中配置此检查器后,它将打印文本编码器与配置的编码器(MTOM、二进制或 GZip)创建的消息大小的差异。 Inspector 的 Send 方法如下所示:

public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
{
var mb = request.CreateBufferedCopy(int.MaxValue);
request = mb.CreateMessage();
var ms = new MemoryStream();

// Dump message size based on text encoder.
using (var memWriter = XmlDictionaryWriter.CreateTextWriter(ms))
{
mb.CreateMessage().WriteMessage(memWriter);
memWriter.Flush();
Console.WriteLine("Message size using text encoder {0}", ms.Position);
}

ms = new MemoryStream();

if (gzipEncoding != null)
{// GZip Special case
var encoder = gzipEncoding.CreateMessageEncoderFactory().CreateSessionEncoder();
encoder.WriteMessage(mb.CreateMessage(), ms);
Console.WriteLine("GZip encoded size {0}", ms.Position);
return null;
}

// just wrap the message – and wrapper will do the trick.

request = new WrappingMessage(request);

return null;
}

public class WrappingMessage : Message
{
Message innerMsg;
MessageBuffer msgBuffer;

public WrappingMessage(Message inner)
{
this.innerMsg = inner;
msgBuffer = innerMsg.CreateBufferedCopy(int.MaxValue);
innerMsg = msgBuffer.CreateMessage();
}

public override MessageHeaders Headers
{
get { return innerMsg.Headers; }
}

protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
{
innerMsg.WriteBodyContents(writer);
}

public override MessageProperties Properties
{
get { return innerMsg.Properties; }
}

public override MessageVersion Version
{
get { return innerMsg.Version; }
}

protected override void OnWriteMessage(XmlDictionaryWriter writer)
{
// write message to the actual stream using encoder..

base.OnWriteMessage(writer);
writer.Flush();

// write message to MemoryStream (using encoder) to get it’s size.
var copy = msgBuffer.CreateMessage();
DumpEncoderSize(writer, copy);
}

private static void DumpEncoderSize(System.Xml.XmlDictionaryWriter writer, Message copy)
{
var ms = new MemoryStream();
string configuredEncoder = string.Empty;
if (writer is IXmlTextWriterInitializer)
{
var w = (IXmlTextWriterInitializer)writer;
w.SetOutput(ms, Encoding.UTF8, true);
configuredEncoder = "Text";
}
else if (writer is IXmlMtomWriterInitializer)
{
var w = (IXmlMtomWriterInitializer)writer;
w.SetOutput(ms, Encoding.UTF8, int.MaxValue, "", null, null, true, false);
configuredEncoder = "MTOM";
}
else if (writer is IXmlBinaryWriterInitializer)
{
var w = (IXmlBinaryWriterInitializer)writer;
w.SetOutput(ms, null, null, false);
configuredEncoder = "Binary";
}

copy.WriteMessage(writer);
writer.Flush();
var size = ms.Position;
Console.WriteLine("Message size using configured ({1}) encoder {0}", size,configuredEncoder);
}
}

关于c# - 如何计算 WCF 服务器发送到客户端的消息流的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34785824/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com