如何确保WCF ChannelFactory在xml配置中使用绑定设置(忽略MaxArrayLength)
嗨,我是Wcf的新手,并且编写了我的第一个Wcf服务和客户端。我不喜欢用 生成配置的工具;我宁愿自己编写配置。我正在尝试的问题 要解决的是客户端通过netTcp与服务进行通信。服务可以 潜在地返回非常大的有效载荷(比默认值更好) ReaderQuotas.MaxArrayLength可以)。我最初开发的组件工作正常 字节流有效载荷相对较低(即小于它认为约为16K的默认值)。 我可以通过创建绑定并设置MaxArrayLength来解决这个问题 到足够大的价值。但是,我需要能够执行等效的 xml配置。
我的app.config(客户端)是:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint address="net.tcp://localhost:9000/WcfDataService/RemoteDataRequesterService/"
binding="netTcpBinding" bindingConfiguration="unsecureNetTcpBinding"
contract="WcfDataServiceLib.IRemoteDataRequester"
name="DataRequesterEndpoint" />
</client>
<bindings>
<netTcpBinding>
<binding name="unsecureNetTcpBinding" maxReceivedMessageSize="2147483647">
<readerQuotas maxArrayLength="1000000" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
创建客户端代理的代码如下:
private void Init()
{
var address = new EndpointAddress(@"net.tcp://localhost:9000/WcfDataService/RemoteDataRequesterService/");
const string endpointName = "DataRequesterEndpoint";
ChannelFactory<IRemoteDataRequester> factory = new ChannelFactory<IRemoteDataRequester>(
endpointName);
IRemoteDataRequester proxy = factory.CreateChannel(address);
// call business methods on proxy ...
}
请注意,代码通过变量'endpointName'链接到配置。
服务端配置(我不认为这是相关的,但包括完整性):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="WcfDataServiceLib.RemoteDataRequesterService" behaviorConfiguration="WcfDataServiceLib.RemoteDataRequesterServiceBehavior">
<host>
<baseAddresses>
<add baseAddress = "net.tcp://localhost:9000/WcfDataService/RemoteDataRequesterService" />
<add baseAddress="http://localhost:8731/Design_Time_Addresses/WcfDataService/RemoteDataRequesterService/"/>
</baseAddresses>
</host>
<endpoint address ="" binding="netTcpBinding" bindingConfiguration="netTcpBindingConfig" contract="WcfDataServiceLib.IRemoteDataRequester">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfDataServiceLib.RemoteDataRequesterServiceBehavior">
<serviceMetadata httpGetEnabled="False"/>
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="netTcpBindingConfig" receiveTimeout="00:00:30">
<readerQuotas maxArrayLength="1000000"/>
</binding>
<binding name="netTcpReliableSession" receiveTimeout="00:00:30" >
<reliableSession enabled="true"/>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
当我在服务返回大字节流的场景中运行客户端时, 抛出异常,异常中的消息是:
发生通信错误:套接字连接中止。这可能是造成的 处理消息时出错或远程主机超出接收超时, 或潜在的网络资源问题。本地套接字超时为'00:00:59.9687494'
(这不是超时,因为错误会立即发生。)
如前所述,我可以通过以下方式对此进行修复:
var binding = new NetTcpBinding
{
ReaderQuotas = { MaxArrayLength = 10000000 }
};
return new ChannelFactory<IRemoteDataRequester>(binding);
这可行,但我需要通过配置来进行测试。
我也尝试了以下内容:
var binding = new NetTcpBinding("unsecureNetTcpBinding");
return new ChannelFactory<IRemoteDataRequester>(binding);
但这没什么区别。
所以我的问题是,当我从端点配置创建包含绑定的通道时 MaxArrayLength设置为合适的值,这个值是否被忽略?
很多问候。
好的,我找到了解决方案。配置一直在努力。但是,我提供的配置(“unsecureNetTcpBinding”),我从一个代码示例中找到了说明http服务(不是我正在设计的net tcp服务)。流氓配置是 '安全模式=“无”' 当我把它拿出来时,它起作用了。如果我更改readerQuotas maxArrayLength,这将按我的要求应用。我的代码工作的原因是因为我没有将安全模式设置为none。感谢您的意见和帮助。
答案 0 :(得分:1)
我认为问题可能是在配置中你的号码只有6个零,而在代码中你有7个零。可能?
答案 1 :(得分:0)
可能MaxArrayLength不适合设置。
尝试“maxBufferSize”和“MaxBufferPoolSize”:
<bindings>
<netTcpBinding>
<binding name="unsecureNetTcpBinding"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxArrayLength="1000000" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
但真正的问题是:如果您有大量数据,为什么不使用WCF streaming?这正是它的设计目标。
http://www.haveyougotwoods.com/archive/2008/04/14/wcf-message-streaming.aspx
maxBufferSize等大小的目的是设置一个相当小的值 - 以避免拒绝服务攻击。只需将那些达到MaxInt级别,这会使您的服务器容易受到这些DOS攻击。
<强>更新强>
试着这样做:
- 创建一个新的控制台应用程序
- 添加对System.Runtime.Serialization
和System.ServiceModel
的引用
- 添加一个app.config,其中包含客户端配置所包含的内容
- 将这些代码放在控制台应用程序中:
class Program
{
static void Main(string[] args)
{
NetTcpBinding binding = new NetTcpBinding("unsecureNetTcpBinding");
int maxArrayLength = binding.ReaderQuotas.MaxArrayLength;
long maxReceivedMessageSize = binding.MaxReceivedMessageSize;
}
}
binding.ReaderQuotas.MaxArrayLength
,“2147483647”代表binding.MaxReceivedMessageSize。WCF确实从配置中识别并使用这些设置 - 120%保证。你的应用程序中一定有其他可疑的东西......