答案 0 :(得分:3)
protobuf-net在大多数数据上通常具有显着节省空间(如:数量级),并且可以附加到WCF。不幸的是目前它不支持完整的图形,只支持树木。但是,我有计划,我根本没有时间实施。我无法承诺任何事情,但我可以尝试更快地完成这项工作。
否则;可能有一些方法可以调整现有代码以使用树而不是图形。
答案 1 :(得分:2)
如果您仍想使用Message Security,我建议您使用MTOM优化传输消息所需的网络带宽,以及在应用安全性时使用较小内存缓冲区的分块通道。否则,WCF将尝试在内存中加载整个消息以应用安全性,因此您将获得内存不足的异常。
答案 2 :(得分:2)
我曾经实现过将大文本传递到wcf或从wcf传递大文本。我的trig将它转换为流并使用GZipStream压缩它然后将其作为byte []发送,幸运的是它永远不会超过10 MB。
在你的情况下,我建议做碎片。将Serialized对象转换为byte [],然后将其合并并解压缩
psudo
int transferSize = 5000000; // 5MB
byte[] compressed = ...;
var mem = new System.IO.MemoryStream(compressed);
for(int i = 0; i < compressed .length; i+= transferSize )
{
byte[] buffer = new byte[transferSize];
mem.Read(buffer, i, compressed);
mem.Flush();
sendFragmentToWCF(buffer);
}
编辑2010年12月8日
基于我的理解,情况是客户端是通过WCF下载一些大的序列化对象。 我没有特别测试这个解决方案,但猜测它应该工作。关键是将序列化对象保存到文件并使用Response传输该文件。
[WebMethod]
public void GetSerializedObject()
{
string path = @"X:\temp.tmp";
var serializer = new System.Runtime.Serialization.NetDataContractSerializer();
var file = new System.IO.FileStream(path, System.IO.FileMode.CreateNew);
try
{
serializer.Serialize(file, ...);
this.Context.Response.TransmitFile(path);
this.Context.Response.Flush();
}
finally
{
file.Flush();
file.Close();
file.Dispose();
System.IO.File.Delete(path);
}
}
WCF会自动执行文件流式传输,因为我们使用文件传输,所以不必担心序列化对象大小。别忘了配置响应限制。
答案 3 :(得分:0)
一些较轻但不保证的解决方案是
DataContractSerializer
,因为您拥有双方。这不需要嵌入式类型信息,这非常大。[DataMember(EmitDefaultValue = false)]
讨论in a question I asked - 再次因为您拥有双方;这样做会减少一些消息大小(当然多少取决于图中默认的字段数)。[DataContract(IsReference=true)]
,特别是如果您有许多重复值对象或参考数据这些当然是权衡,例如具有可读性。
答案 4 :(得分:0)
由于没有人将其付诸实施,因此使用WebSockets或long polling技术或许可以解决此问题。我只是简单地研究了这些解决方案,并没有围绕它们制定解决方案,但我想提出这些概念进行记录,如果时间允许,我会在稍后的时间点扩展我的答案。
基本思想是实现类似于ChunkingChannel示例如何工作的想法,但不需要全双工通道,这通常会破坏端口80基于Web的请求/响应模型,这是避免必须进行的防火墙和客户端的其他相关配置。
其他相关材料:
更新:在对此进行更多研究后,似乎通过使用称为NetHttpBinding的WebSockets,我本来就不会解决在WCF中使用带有消息安全性的wsHttp的原始请求。我将在这里保留我的答案,但作为其他可能正在寻找替代方案的人的信息。