gpt4 book ai didi

wcf - NetTCP 和二进制传输

转载 作者:行者123 更新时间:2023-12-01 12:59:55 26 4
gpt4 key购买 nike

我有一个带有 HTTP 绑定(bind)的 WCF 服务,它返回 500k 大小的数据集。使用 WCF 默认日志记录时,我可以看到消息和随每条消息传输的数据

  <system.serviceModel>
<!-- add trace logging -->
<diagnostics wmiProviderEnabled="true">
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
/>
</diagnostics>

....

<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add initializeData="c:\nettcpTestLOCALToTEST.xml" type="System.Diagnostics.XmlWriterTraceListener"
name="messages">
<filter type="" />
</add>
</listeners>
</source>
</sources>
</system.diagnostics>

要点是,我正在寻找一种减少服务器和客户端之间流量的方法,有人告诉我 NetTCP 正在传输数据二进制文件?对吗?

我已经使用 NetTCPBinding 设置了一个测试场景,当我在客户端读取 WCF 时,响应消息包括整个数据集架构和 XML 格式的数据。它只是序列化以便可以写入日志,还是此消息是二进制传输的?

使用 NetTCP 绑定(bind)传输的数据量是否小于使用 HTTPBinding 传输的数据量?是文本还是二进制?

提前致谢

最佳答案

是的,消息将以二进制形式传输,但序列化程序(我假设是 Datacontractserializer)将以 XML 格式序列化数据:

Use the DataContractSerializer class to serialize and deserialize instances of a type into an XML stream or document

DataContractSerializer来自文档:

The NetTcpBinding generates a run-time communication stack by default, which uses transport security, TCP for message delivery, and a binary message encoding. This binding is an appropriate system-provided choice for communicating over an Intranet.

NetTcpBinding MSDN

如果您选择实现 ISerializable,您也可以使用 WCF,但您必须实现 DataContractResolver 来解析类型:如果客户端“知道”类型(例如,您将它们放入 dll 并将它们添加到客户端- app) 你可以使用下面的示例代码这应该以更紧凑的形式产生序列化。



type internal SharedTypeResolver() =
inherit System.Runtime.Serialization.DataContractResolver()

let dict = new Xml.XmlDictionary()

override this.TryResolveType(t : Type, declaredT : Type, knownTypeResolver : System.Runtime.Serialization.DataContractResolver, typeName : Xml.XmlDictionaryString byref, typeNamespace : Xml.XmlDictionaryString byref) =
typeNamespace = dict.Add(t.Assembly.FullName)
typeName = dict.Add(t.FullName)
true

override this.ResolveName(typeName : string, typeNamespace : string, declaredType : Type, knownTypeResolver : System.Runtime.Serialization.DataContractResolver) =
let res = knownTypeResolver.ResolveName(typeName, typeNamespace, declaredType, null)
if res = null then Type.GetType(typeName + ", " + typeNamespace) else res

PS: 在 C# 中发现相同的:


public class SharedTypeResolver : DataContractResolver
{
#region Overrides of DataContractResolver

///
/// Override this method to map a data contract type to an xsi:type name and namespace during serialization.
///
///
/// true if mapping succeeded; otherwise, false.
///
/// The type to map.The type declared in the data contract.The known type resolver.The xsi:type name.The xsi:type namespace.
public override bool TryResolveType(Type type, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
{
if (!knownTypeResolver.TryResolveType(type, declaredType, null, out typeName, out typeNamespace))
{
var dict = new XmlDictionary(); // nice trick to get the right type for typeName
if (type != null)
{
typeNamespace = dict.Add(type.Assembly.FullName);
typeName = dict.Add(type.FullName);
}
else
{
typeNamespace = dict.Add("noAss");
typeName = dict.Add("noType");
}
}
return true;
}

///
/// Override this method to map the specified xsi:type name and namespace to a data contract type during deserialization.
///
///
/// The type the xsi:type name and namespace is mapped to.
///
/// The xsi:type name to map.The xsi:type namespace to map.The type declared in the data contract.The known type resolver.
public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)
{
return knownTypeResolver.ResolveName(typeName, typeNamespace, declaredType, null) ??
Type.GetType(typeName + ", " + typeNamespace);
}

(请注意:stackoverflow 不喜欢 F# 中的赋值运算符“<-”,我不知道如何规避 - 因此我使用了“=”)哦,好吧 - 我想我必须说一下如何将这些解析器添加到您的主机:


private static void AddResolver(OperationDescription operationDescription)
{
if (operationDescription == null)
throw new ArgumentNullException();

var serializationBehavior = operationDescription.Behaviors.Find();
if (serializationBehavior == null)
{
serializationBehavior = new DataContractSerializerOperationBehavior(operationDescription);
operationDescription.Behaviors.Add(serializationBehavior);
}
serializationBehavior.DataContractResolver = new SharedTypeResolver();
}

将其用于:



var contrDescription = _host.Description.Endpoints[0].Contract;
var description= contrDescription.Operations.Find("MyServiceMethod");
AddResolver(description);


用您的服务方法的名称替换“MyServiceMethod”(按方法调用或迭代所有方法)

关于wcf - NetTCP 和二进制传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7121525/

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