我需要将一个大型数组传递给WCF服务。
当我试图这样做时,我收到了CommunicationException:
The socket connection was aborted. This could be caused by an error processing
your message or a receive timeout being exceeded by the remote host, or an
underlying network resource issue. Local socket timeout was '24.00:59:59.9649980'.
我该如何解决?
代码:
服务器:
[ServiceContract(CallbackContract = typeof(ICallback))]
public interface IService
{
[OperationContract]
string Ping(string name);
[OperationContract]
int Count(string[] data);
}
public interface ICallback
{
[OperationContract]
void OnPing(string pingText, DateTime time);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class ServiceImplementation : IService
{
#region IService Members
public string Ping(string name)
{
Semaphore wait = new Semaphore(0,1);
//get the callback item
var callback = OperationContext.Current.GetCallbackChannel<ICallback>();
if (callback!=null)
{
new Thread(() =>
{
wait.WaitOne();
callback.OnPing(name, DateTime.Now);
}).Start();
}
Console.WriteLine("SERVER - Processing Ping('{0}')", name);
wait.Release();
return "Hello, " + name;
}
#endregion
public int Count(string[] data)
{
return data.Count();
}
}
private static System.Threading.AutoResetEvent stopFlag = new System.Threading.AutoResetEvent(false);
public static void Main()
{
ServiceHost svh = new ServiceHost(typeof(ServiceImplementation));
svh.AddServiceEndpoint(typeof(IService), new NetTcpBinding(), "net.tcp://localhost:8000");
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = svh.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
smb = new ServiceMetadataBehavior();
//smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
svh.Description.Behaviors.Add(smb);
// Add MEX endpoint
svh.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexTcpBinding(),
"net.tcp://localhost:8000/mex"
);
svh.Open();
Console.WriteLine("SERVER - Running...");
stopFlag.WaitOne();
Console.WriteLine("SERVER - Shutting down...");
svh.Close();
Console.WriteLine("SERVER - Shut down!");
}
public static void Stop()
{
stopFlag.Set();
}
client:
class Callback : IServiceCallback
{
static int s;
int id = 0;
public Callback()
{
id = s++;
}
public void OnPing(string pingText, DateTime time)
{
Console.WriteLine("\r\n{2}:Callback on \"{0}\"\t{1}",pingText,time,id);
}
}
static Random rnd = new Random();
static string GenetateStuff(int length)
{
StringBuilder sb = new StringBuilder();
string s = "',.pyfgcrlaoeuidhtns;qjkxbmwvsz";
for (int i = 0; i < length; i++)
{
sb.Append(s[rnd.Next(s.Length)]);
}
return sb.ToString();
}
static void Main(string[] args)
{
InstanceContext ctx = new InstanceContext(new Callback());
ServiceClient client = new ServiceClient(ctx);
List<string> data = new List<string>();
for (int i = 0; i < 10000; i++)
{
data.Add(GenetateStuff(10000));
}
Console.WriteLine(client.Count(data.ToArray()));
}
client xml:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IService" closeTimeout="24:01:00"
openTimeout="24:01:00" receiveTimeout="24:10:00" sendTimeout="24:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8000/" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IService" contract="TestTcpService.IService"
name="NetTcpBinding_IService">
<identity>
<userPrincipalName value="badasscomputing\menkaur" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
可以下载完整的项目here。
答案 0 :(得分:4)
替换以下行
svh.AddServiceEndpoint(typeof(IService), new NetTcpBinding(), "net.tcp://localhost:8000");
带
var tcpbinding = new NetTcpBinding();
tcpbinding.MaxReceivedMessageSize = 2147483647;
tcpbinding.ReaderQuotas.MaxArrayLength = 2147483647;
tcpbinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
tcpbinding.ReaderQuotas.MaxStringContentLength = 2147483647;
tcpbinding.ReaderQuotas.MaxDepth = 2147483647;
svh.AddServiceEndpoint(typeof(IService), tcpbinding, "net.tcp://localhost:8000");
注意:参考System.Runtime.Serialization.dll并导入命名空间
这应该增加所有大小的默认限制,应该没问题。同样找到通过代码添加maxObjInItemGraph的方法。