对一个WCF Web serivces响应大小limitaiton [英] response size limitaiton of a WCF web serivces

查看:242
本文介绍了对一个WCF Web serivces响应大小limitaiton的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在IIS中使用basicHttpBinding的托管WCF服务。 WCF的Web服务查询后端SQL Server 2008中使用ADO.Net,并返回一个DataTable到WCF服务的客户端。

我发现当返回的DataTable较大,会有异常说http连接是通过IIS关闭。任何想法是错误的,如何设置更大的响应大小?另一个想法是,是否存在一个对象的序列化大小的任何硬限制,(我想也许DataTable实例太大序列化?)

由IIS返回的错误信息是:

  

异常消息:

     

在接收时出错   HTTP响应    HTTP://labmachine1/service.svc 。本   可能是由于服务端点   不使用HTTP协议绑定。   这也可能是由于一个HTTP   请求上下文被中止的   服务器(可能是由于服务   关闭)。请参阅服务器日志   更多的细节。

     

{基础连接已经关闭:发生意外错误   在接收。}

下面是我的全部源$ C ​​$ C服务器端,服务器主机我在web.config中,没有变化的默认值。由于在IIS中我的主机,我使用basicHttpBinding的。

 公共类StudentManagement:IStudentManagement
{
    公众投票数据表(INT标识)
    {
        返回MakeParentTable();
    }

    私人数据表MakeParentTable()
    {
        //创建一个新的DataTable。
        System.Data.DataTable表=新的DataTable(ParentTable);
        //申报的DataColumn和DataRow对象变量。
        DataColumn的列;
        DataRow的列;

        //创建新的DataColumn,设置数据类型,
        //,ColumnName和添加到数据表。
        列=新的DataColumn();
        column.DataType = System.Type.GetType(System.Int32的);
        column.ColumnName =ID;
        column.ReadOnly = TRUE;
        column.Unique =真;
        //列添加到DataColumnCollection。
        table.Columns.Add(列);

        //创建第二列。
        列=新的DataColumn();
        column.DataType = System.Type.GetType(System.String);
        column.ColumnName =ParentItem;
        column.AutoIncrement = FALSE;
        column.Caption =ParentItem;
        column.ReadOnly = FALSE;
        column.Unique = FALSE;
        //列添加到表中。
        table.Columns.Add(列);

        //使ID列主键列。
        的DataColumn [] PrimaryKeyColumns =新的DataColumn [1];
        PrimaryKeyColumns [0] = table.Columns [ID];
        table.PrimaryKey = PrimaryKeyColumns;

        //创建三个新的DataRow对象,并添加
        他们//到DataTable
        的for(int i = 0; I< = 1000000;我++)
        {
            行= table.NewRow();
            行[身份证] =我;
            行[ParentItem] =ParentItem+我;
            table.Rows.Add(行);
        }

        返回表;
    }
}
 

客户端code:

 静态无效的主要(字串[] args)
{
    StudentIdentifier标识符=新StudentIdentifier();
    identifier.Id = 100;
    StudentManagementClient客户端=新StudentManagementClient();

    DataTable的学生= client.Poll(标识);

    Console.WriteLine(student.Rows.Count);
}
 

客户端的web.config:

 <绑定名称=BasicHttpBinding_IStudentManagementcloseTimeout =0点01分零零秒
    openTimeout =00:01:00receiveTimeout =00:10:00的SendTimeout =00:01:00
    allowCookies =假bypassProxyOnLocal =假
    hostNameComparisonMode =StrongWildcard
    maxBufferSize =10亿maxBufferPoolSize =10亿
    maxReceivedMessageSize =10亿
    messageEncoding =文本textEncoding =UTF-8transferMode =缓冲
    useDefaultWebProxy =真正的>
    < readerQuotas MAXDEPTH =32maxStringContentLength =10亿
        maxArrayLength =10亿
        maxBytesPerRead =4096maxNameTableCharCount =16384/>
< /装订>
 

编辑2:

有关客户端的app.config流模式配置,

 < basicHttpBinding的>
      <绑定名称=BasicHttpBinding_IStudentManagementcloseTimeout =00:01:00
        openTimeout =00:20:00receiveTimeout =01:00:00的SendTimeout =01:00:00
        allowCookies =假bypassProxyOnLocal =假hostNameComparisonMode =StrongWildcard
        maxBufferSize =15亿maxBufferPoolSize =15亿maxReceivedMessageSize =15亿
        messageEncoding =MTOMtextEncoding =UTF-8transferMode =流媒体
        useDefaultWebProxy =真正的>
        < readerQuotas MAXDEPTH =15亿maxStringContentLength =15亿
          maxArrayLength =15亿maxBytesPerRead =15亿maxNameTableCharCount =15亿/>
        <安全模式=无>
          <交通运输clientCredentialType =无proxyCredentialType =无
            境界=/>
          <消息clientCredentialType =用户名algorithmSuite =默认/>
        < /安全>
      < /装订>
    < / basicHttpBinding的>
 

服务器端的web.config的流模式,

 < basicHttpBinding的>
    <绑定名称=BasicHttpBinding_IStudentManagementcloseTimeout =00:01:00
        openTimeout =00:20:00receiveTimeout =01:00:00的SendTimeout =01:00:00
        allowCookies =假bypassProxyOnLocal =假hostNameComparisonMode =StrongWildcard
        maxBufferSize =10亿maxBufferPoolSize =10亿maxReceivedMessageSize =10亿
        messageEncoding =MTOMtextEncoding =UTF-8transferMode =流媒体
        useDefaultWebProxy =真正的>
      < readerQuotas MAXDEPTH =32maxStringContentLength =10亿maxArrayLength =10亿
          maxBytesPerRead =4096maxNameTableCharCount =16384/>
      <安全模式=无>
        <交通运输clientCredentialType =无proxyCredentialType =无
            境界=/>
        <消息clientCredentialType =用户名algorithmSuite =默认/>
      < /安全>
    < /装订>
  < / basicHttpBinding的>
 

解决方案

有许多缓冲区的大小,你可以玩 - 他们是为了避免拒绝服务攻击保持相当小(64K)默认,但如果你需要,可以增加这些:

 < system.serviceModel>
    <绑定>
        < basicHttpBinding的>
            <绑定名称=largebufferscloseTimeout =00:01:00
                openTimeout =00:01:00receiveTimeout =00:10:00的SendTimeout =00:01:00
                bypassProxyOnLocal =假transactionFlow =假
                hostNameComparisonMode =StrongWildcard
                maxBufferSize =524288maxBufferPoolSize =524288
                maxReceivedMessageSize =65536
                messageEncoding =文本textEncoding =UTF-8useDefaultWebProxy =真
                allowCookies =假>
                < readerQuotas MAXDEPTH =32maxStringContentLength =8192
                              maxArrayLength =16384maxBytesPerRead =4096
                              maxNameTableCharCount =16384/>
            < /装订>
        < / basicHttpBinding的>
    < /绑定>
 

有一个看看MaxBufferSize,MaxBufferPoolSize,MaxReceivedMessageSizesettingsin的结合,以及各种在&LT设置; readerQuotas> 部分。

我会尝试只是增加了MaxBufferSize和MaxBufferPoolSize首先,看看有没有单独帮助 - 大多数其他的设置应真的当服务接收并需要处理邮件实现更为适合。

有没有硬性的限制作为一个对象有多大可以是序列化回来。但是,数据表点上有显著的开销,如果你不真的需要在客户端数据表功能,你也可以做一个转换的服务器上,以送回来只是一个集合或对象泛型列表 - 而不是重型DataTable对象。

此外,如果你经常发回大量数据,你可能需要调查WCF的流媒体功能,太(例如,如果你返回图片,视频,这样的东西)。 马克·

I am hosting a WCF service in IIS using basicHttpBinding. The WCF web services queries back end SQL Server 2008 by using ADO.Net and return a DataTable to client side of WCF service.

I find when the returned DataTable is big, there will be exception said http connection is closed by IIS. Any ideas what is wrong and how to set bigger response size? Another idea is whether there is any hard limitation for the serialization size of an object (I thought maybe the DataTable instance is too big to serialize?)

The error information returned by IIS is:

Exception message:

An error occurred while receiving the HTTP response to http://labmachine1/service.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.

{"The underlying connection was closed: An unexpected error occurred on a receive."}

Here is my whole source code for server side, for the server I host in web.config, no change for default values. Since I host in IIS, I am using basicHttpBinding.

public class StudentManagement : IStudentManagement
{
    public DataTable Poll(int Id)
    {
        return MakeParentTable();
    }

    private DataTable MakeParentTable()
    {
        // Create a new DataTable.
        System.Data.DataTable table = new DataTable("ParentTable");
        // Declare variables for DataColumn and DataRow objects.
        DataColumn column;
        DataRow row;

        // Create new DataColumn, set DataType, 
        // ColumnName and add to DataTable.    
        column = new DataColumn();
        column.DataType = System.Type.GetType("System.Int32");
        column.ColumnName = "id";
        column.ReadOnly = true;
        column.Unique = true;
        // Add the Column to the DataColumnCollection.
        table.Columns.Add(column);

        // Create second column.
        column = new DataColumn();
        column.DataType = System.Type.GetType("System.String");
        column.ColumnName = "ParentItem";
        column.AutoIncrement = false;
        column.Caption = "ParentItem";
        column.ReadOnly = false;
        column.Unique = false;
        // Add the column to the table.
        table.Columns.Add(column);

        // Make the ID column the primary key column.
        DataColumn[] PrimaryKeyColumns = new DataColumn[1];
        PrimaryKeyColumns[0] = table.Columns["id"];
        table.PrimaryKey = PrimaryKeyColumns;

        // Create three new DataRow objects and add 
        // them to the DataTable
        for (int i = 0; i <= 1000000; i++)
        {
            row = table.NewRow();
            row["id"] = i;
            row["ParentItem"] = "ParentItem " + i;
            table.Rows.Add(row);
        }

        return table;
    }
}

Client side code:

static void Main(string[] args)
{
    StudentIdentifier identifier = new StudentIdentifier();
    identifier.Id = 100;
    StudentManagementClient client = new StudentManagementClient();

    DataTable student = client.Poll(identifier);

    Console.WriteLine(student.Rows.Count);
}

Client side web.config:

<binding name="BasicHttpBinding_IStudentManagement" closeTimeout="00:01:00"
    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
    allowCookies="false" bypassProxyOnLocal="false" 
    hostNameComparisonMode="StrongWildcard"
    maxBufferSize="1000000000" maxBufferPoolSize="1000000000" 
    maxReceivedMessageSize="1000000000"
    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
    useDefaultWebProxy="true">
    <readerQuotas maxDepth="32" maxStringContentLength="1000000000" 
        maxArrayLength="1000000000"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>

EDIT 2:

Streaming mode configuration for client side app.config,

    <basicHttpBinding>
      <binding name="BasicHttpBinding_IStudentManagement" closeTimeout="00:01:00"
        openTimeout="00:20:00" receiveTimeout="01:00:00" sendTimeout="01:00:00"
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
        maxBufferSize="1500000000" maxBufferPoolSize="1500000000" maxReceivedMessageSize="1500000000"
        messageEncoding="Mtom" textEncoding="utf-8" transferMode="Streamed"
        useDefaultWebProxy="true">
        <readerQuotas maxDepth="1500000000" maxStringContentLength="1500000000"
          maxArrayLength="1500000000" maxBytesPerRead="1500000000" maxNameTableCharCount="1500000000" />
        <security mode="None">
          <transport clientCredentialType="None" proxyCredentialType="None"
            realm="" />
          <message clientCredentialType="UserName" algorithmSuite="Default" />
        </security>
      </binding>
    </basicHttpBinding>

Server side web.config for streaming mode,

  <basicHttpBinding>
    <binding name="BasicHttpBinding_IStudentManagement" closeTimeout="00:01:00"
        openTimeout="00:20:00" receiveTimeout="01:00:00" sendTimeout="01:00:00"
        allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
        maxBufferSize="1000000000" maxBufferPoolSize="1000000000" maxReceivedMessageSize="1000000000"
        messageEncoding="Mtom" textEncoding="utf-8" transferMode="Streamed"
        useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="1000000000" maxArrayLength="1000000000"
          maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None"
            realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
    </binding>
  </basicHttpBinding>

解决方案

There's a multitude of buffer sizes you can play with - they are kept fairly small (64K) by default in order to avoid Denial-of-service attacks, but if you need to, you can increase those:

 <system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="largebuffers" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                bypassProxyOnLocal="false" transactionFlow="false" 
                hostNameComparisonMode="StrongWildcard"
                maxBufferSize="524288" maxBufferPoolSize="524288" 
                maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                allowCookies="false">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" 
                              maxArrayLength="16384" maxBytesPerRead="4096" 
                              maxNameTableCharCount="16384" />
            </binding>
        </basicHttpBinding>
    </bindings>

Have a look at the "MaxBufferSize", "MaxBufferPoolSize", "MaxReceivedMessageSize" settingsin the binding, as well as the various settings in the <readerQuotas> section.

I would try to just increase the "MaxBufferSize" and "MaxBufferPoolSize" first and see if that alone helps - most of the other settings should really be more geared towards when the service receives and needs to process a message.

There are no hard limits as to how big an object can be that you serialize back. However, the DataTable does carry a significant overhead, and if you don't really need that DataTable functionality on the client side, you might also do a conversion on the server to send back just a collection or generic list of objects - instead of the heavy-lift DataTable object.

Furthermore, if you frequently send back large amounts of data, you might need to investigate the streaming capabilities of WCF, too (e.g. if you return pictures, videos, that kind of stuff). Marc

这篇关于对一个WCF Web serivces响应大小limitaiton的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆