簡體   English   中英

將大型數組傳遞給WCF服務

[英]Passing a large array to a WCF service

我需要將一個大型數組傳遞到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>

完整的項目可以在這里下載。

替換以下行

    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的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM