我使用basicHttpBinding在IIS中托管WCF服务.WCF Web服务使用ADO.Net查询后端SQL Server 2008,并将DataTable返回到WCF服务的客户端.
我发现当返回的DataTable很大时,会有异常表示http连接被IIS关闭.任何想法有什么不对,以及如何设置更大的响应大小?另一个想法是对象的序列化大小是否有任何硬性限制(我想可能DataTable实例太大而不能序列化?)
IIS返回的错误信息是:
异常消息:
收到http://labmachine1/service.svc的HTTP响应时发生错误 .这可能是由于服务端点绑定不使用HTTP协议.这也可能是由于服务器中止HTTP请求上下文(可能是由于服务关闭).请参阅服务器日志以获取更多详
{"底层连接已关闭:接收时发生意外错误."}
这是我的服务器端的完整源代码,对于我在web.config中托管的服务器,默认值没有变化.由于我在IIS中托管,我使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
客户端代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
客户端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>
Run Code Online (Sandbox Code Playgroud)
编辑2:
客户端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>
Run Code Online (Sandbox Code Playgroud)
用于流模式的服务器端web.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="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>
Run Code Online (Sandbox Code Playgroud)
您可以使用多种缓冲区大小 - 默认情况下它们保持相当小(64K)以避免拒绝服务攻击,但如果您需要,可以增加以下内容:
<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>
Run Code Online (Sandbox Code Playgroud)
看一下绑定中的"MaxBufferSize","MaxBufferPoolSize","MaxReceivedMessageSize"设置,以及该<readerQuotas>部分中的各种设置.
我会尝试首先增加"MaxBufferSize"和"MaxBufferPoolSize",看看是否有帮助 - 大多数其他设置应该更加适应服务接收和需要处理消息的时间.
对于序列化后的对象有多大没有硬性限制.但是,DataTable确实会带来很大的开销,如果您在客户端并不真的需要DataTable功能,那么您也可以在服务器上进行转换以仅发回一个集合或通用的对象列表 - 而不是重型DataTable对象.
此外,如果您经常发送大量数据,您可能还需要调查WCF的流媒体功能(例如,如果您返回图片,视频,那种东西).渣
| 归档时间: |
|
| 查看次数: |
18753 次 |
| 最近记录: |