Доброго времени суток.
Играясь с wcf столкнулся со следующей проблемой. Не получается увеличить число одновременных подключений клиентов к сервису. Подключается 14 а остальные отсекаются, при том в абсолютно непредсказуемом порядке. Посоветуйте, как можно это решить или где хотя бы покопаться на эту тему. Прочитал про настройки дросселирования и увеличил maxconnections в настройках netTcpBinding'а. Не помогает. Вот мой тестовый пример, на котором отрабатывал тесты (не судите строго за возможную кривизну — сделано на скорую руку).
Помогите, а то уже давно бьюсь над этой проблемой.
Контракт:
namespace TestContract
{
[ServiceContract(SessionMode=SessionMode.NotAllowed,
Namespace="
http://www.labma.ru/IB")]
public interface ITestContract
{
[OperationContract(Action = "
http://www.labma.ru/IB/Provider/LogOperation")]
void LongOperation(int timeInterval);
}
}
Код сервиса:
namespace Host.Service
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class TestService : ITestContract
{
public void LongOperation(int timeInterval)
{
Thread.Sleep(timeInterval * 1000);
}
}
}
Код клиента:
namespace Host.Client
{
public class Client<T> : ClientBase<T> where T : class
{
public new T Channel
{
get { return base.Channel; }
}
}
public class Program
{
private static object synchObj = new object();
private const int requestQuantity = 100;
private const int timeInterval = 10; //sec
public static int successful = 0;
public static int failed = 0;
public static void Main(string[] args)
{
Console.WriteLine("Wait for service started then press any key");
Console.ReadKey();
Thread[] th = new Thread[requestQuantity];
try
{
for (int i = 0; i < requestQuantity; i++)
{
NumberParameter par = new NumberParameter(i);
th[i] = new Thread(par.CallLongOperation);
th[i].Start();
}
for (int i = 0; i < requestQuantity; i++)
th[i].Join();
}
catch (Exception ex)
{
Console.WriteLine("Error during long operation: " + ex.Message);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Console.WriteLine(String.Format("successful {0}", successful));
Console.WriteLine(String.Format("failed {0}", failed));
Console.WriteLine(String.Format("total {0}", requestQuantity));
Console.WriteLine("End");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
public class NumberParameter
{
int i;
public NumberParameter(int par)
{
i = par;
}
public void CallLongOperation()
{
Console.WriteLine(String.Format("Start of CallLongOperation inside. Number {0}", i));
try
{
using (var client = new Client<ITestContract>())
client.Channel.LongOperation(timeInterval);
}
catch (Exception ex)
{
Console.WriteLine(String.Format("Error when calling CallLongOperation inside. Number {0} : {1}", i, ex.ToString()));
lock (synchObj)
failed++;
return;
}
Console.WriteLine(String.Format("Work of of CallLongOperation successfully completed. Number {0}", i));
lock (synchObj)
successful++;
}
}
}
Код хоста сервиса:
public static void Main(string[] args)
{
try
{
ServiceHost sh = new ServiceHost(typeof(TestService));
sh.Open();
}
catch (Exception ex)
{
Console.WriteLine("host start exception: " + ex.ToString());
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Код хоста клиента:
public class Program
{
private static object synchObj = new object();
private const int requestQuantity = 100;
private const int timeInterval = 10; //sec
public static int successful = 0;
public static int failed = 0;
public static void Main(string[] args)
{
Console.WriteLine("Wait for service started then press any key");
Console.ReadKey();
Thread[] th = new Thread[requestQuantity];
try
{
for (int i = 0; i < requestQuantity; i++)
{
NumberParameter par = new NumberParameter(i);
th[i] = new Thread(par.CallLongOperation);
th[i].Start();
}
for (int i = 0; i < requestQuantity; i++)
th[i].Join();
}
catch (Exception ex)
{
Console.WriteLine("Error during long operation: " + ex.Message);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Console.WriteLine(String.Format("successful {0}", successful));
Console.WriteLine(String.Format("failed {0}", failed));
Console.WriteLine(String.Format("total {0}", requestQuantity));
Console.WriteLine("End");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
public class NumberParameter
{
int i;
public NumberParameter(int par)
{
i = par;
}
public void CallLongOperation()
{
Console.WriteLine(String.Format("Start of CallLongOperation inside. Number {0}", i));
try
{
using (var client = new Client<ITestContract>())
client.Channel.LongOperation(timeInterval);
}
catch (Exception ex)
{
Console.WriteLine(String.Format("Error when calling CallLongOperation inside. Number {0} : {1}", i, ex.ToString()));
lock (synchObj)
failed++;
return;
}
Console.WriteLine(String.Format("Work of of CallLongOperation successfully completed. Number {0}", i));
lock (synchObj)
successful++;
}
}
}
Конфиг сервиса:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="StrmWin" transferMode="Streamed" sendTimeout="01:00:00" receiveTimeout="01:00:00"
openTimeout="01:00:00" closeTimeout="01:00:00" maxReceivedMessageSize="10000000000"
maxConnections="1200">
<readerQuotas maxBytesPerRead="512000000" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Host.Service.TestService" behaviorConfiguration="LimitConnectionsBehavior" >
<endpoint name="IProvider" contract="TestContract.ITestContract" binding="netTcpBinding"
bindingConfiguration="StrmWin" address="
net.tcp://localhost:7000/Provider" />
<host>
<baseAddresses>
<add baseAddress="
http://localhost:8000/Provider" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ExceptionDetails">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="PublishMetadata">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="LimitConnectionsBehavior">
<serviceThrottling maxConcurrentInstances="10" maxConcurrentCalls="200" maxConcurrentSessions="200"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Конфиг клиента:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="StrmWin" transferMode="Streamed" sendTimeout="01:00:00" receiveTimeout="01:00:00"
maxReceivedMessageSize="10000000000" maxConnections="1200" openTimeout="01:00:00" closeTimeout="01:00:00">
<readerQuotas maxBytesPerRead="512000000" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint name="IProvider" contract="TestContract.ITestContract"
binding="netTcpBinding" bindingConfiguration="StrmWin"
address="
net.tcp://localhost:7000/Provider" behaviorConfiguration=""/>
</client>
<!--<behaviors>
<endpointBehaviors>
<behavior name="asd">
<
</behavior>
</endpointBehaviors>
</behaviors>-->
</system.serviceModel>
Здравствуйте, baranovda, Вы писали:
B>Здравствуйте, Ogrampir, Вы писали:
O>>Запустил тестовый хост на серваке с Windows 2003 Server Enterp. Edition, клиент со своей машины.
O>>Все равно грохается.
B>Что в исключении пишется?
Вот исключение:
Error when calling CallLongOperation inside. Number 28 : System.ServiceModel.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 '00:59:59.9687500'. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.ServiceModel.Channels.SocketConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.SocketConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
at System.ServiceModel.Channels.BufferedConnection.WriteNow(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, BufferManager bufferManager)
at System.ServiceModel.Channels.BufferedConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
at System.ServiceModel.Channels.StreamedFramingRequestChannel.SendPreamble(IConnection connection, TimeoutHelper& timeoutHelper, ClientFramingDecoder de
coder, SecurityMessageProperty& remoteSecurity)
at System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper&
timeoutHelper)
at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
at System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedFramingRequest.SendRequest(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpa
n timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at TestContract.ITestContract.LongOperation(Int32 timeInterval)
at Host.Client.Program.NumberParameter.CallLongOperation() in D:\test\Host.Client\Program.cs:line 72