Method Call Timeouts

(Lagarrigue, Frederic (Reigate)) #1

I’m trying to call a service method in a C# server from a Delphi client. The C# server is also a client and makes another subsequent call. My problem occurs if that second call takes longer than a minute. there seems to be a timeout and I get a ConnectionClosedException on the first connection. I can call either synchronously or asynchronously, but I still get the connection closed. A split second after 1 minute. Is there a connection timeout when making calls?

(EvgenyK) #3

I can recommend to use async calls via _AsyncEx interface.
in this case, ConnectionClosedException will be not raised on delphi side.

by other hand, you can just increase timeout on channel component

(Lagarrigue, Frederic (Reigate)) #4

Setting the timeoutenabled property of the http client channel on ,NET solved the problem. The Delphi client timeout was -1 anyway. Thanks

(Lagarrigue, Frederic (Reigate)) #5

I spoke too soon. It’s better but seems to timeout after about 3 minutes. That’s with a sync call from a .net client with timoutenabled = false.

(antonk) #6

Which exactly clist channel type do you use in .NET ?

(Lagarrigue, Frederic (Reigate)) #7

The client is a IpHttpClientChannel.

(antonk) #8

Could you show more info on the exception? Ie its stacktrace and exact error message?

Thanks in advance

(Lagarrigue, Frederic (Reigate)) #9

The exception is - RemObjects.SDK.Exceptions.ConnectionClosedException

The stack trace :
at RemObjects.SDK.Http.HttpClient.TryDispatch(HttpClientRequest request) at RemObjects.SDK.IpHttpClientChannel.IntDispatch(Stream request, IMessage response) at RemObjects.SDK.ClientChannel.Dispatch(IMessage message) at WTW.ResQ.Server.AgentService_Proxy.RunValidationEx(Int64 aUserId, Int64 aProjectId, String aUniqueId, Int32 aTest, Boolean aFix) in G:\Development\ResQ\RESQ GIT\resq\ResQServer\WTW.ResQ.Server\WTW.ResQ.Server.Services\AgentAccess\ResQAgent_Intf.cs:line 13695 at WTW.ResQ.Server.Services.MechanismService.<>c__DisplayClass29_0.b__0() in G:\Development\ResQ\RESQ GIT\resq\ResQServer\WTW.ResQ.Server\WTW.ResQ.Server.Services\Services\MechanismService.cs:line 706 at WTW.ResQ.Server.ResQServerApplicationServer.Execute(Action action, ISession session, String methodName, Service serverService, IAgentService agentService, Boolean timeIt, ServiceLog serviceLog) in G:\Development\ResQ\RESQ GIT\resq\ResQServer\WTW.ResQ.Server\WTW.ResQ.Server.Services\ResQServerApplicationServer.cs:line 258

(Lagarrigue, Frederic (Reigate)) #10

Is there any progress here? This is stopping our work, and to be honest, this issue is beginning to make us lose confidence in remoting sdk. Hopefully it’s something we are doing wrong…

(antonk) #11

Sure, we’re working on the issue. You’ll get the answer once we make a progress on this.

Btw wht exactly .NET version of SDK do you use and do you use SSL somewhere in the call chain?

(antonk) #12

Unfortunately I cannot reproduce the issue.

I’ve attached a testcase where a client app calls a .NET server which in its turn calls another .NET server and executes a 4-minutes long operation (remote server just sleeps for 4 minutes before returning the result). Please take a look and if possible modify the testcase to make the issue reappear (f.e. your remote server might be using other type of server channel etc): (121.7 KB)

(Lagarrigue, Frederic (Reigate)) #13

I’ll try the same test in our application. i.e. just do a test with various pauses. Just to confirm the problem happens at 3 minutes. Our application is a Delphi Client - .NET server/client - Delphi server.

I’ll then try your test application and see what happens. We are using .NET framework 4.5.2. and we have SSL between the Delphi client and .NET server, but the problem seems to be between the .net client and the Delphi server.

(antonk) #14

Hmm, it was not clear that the “most remote” server you have is also Delphi-based one. This might explain why we had troubles reproducing the issue,because we wrongly assumed it was .NET based too.

Could you say which exactly server channel you use there and show the properties of that channel?

(Lagarrigue, Frederic (Reigate)) #16

On the Delphi server we us a TROIpSuperHTTPServer with a BinMessage. Apart from the server Name and the port number, all default properties. We use an TROInMemorySessionManager, again all defaults. And finally an TROInMemoryEventRepository. On the .NET server/clent, we use the IPHTTPclientChannel with timeoutenabled set to false. Again we use the bin message. On the server part of the .NET application we use the app.config file to use superhttp:

<ServerChannel type=“superhttp” port=“8099”/>
<ServerMessage type=“bin” />
<SslOptions useTLS =“true” generateCertificate=“true”/>

On the Delphi client we use the TROIndyHTTPClient. I’m not quite sure why we don’t use the super client here. An oversight. again pretty much default properties.

(EvgenyK) #17

default timeout of TROIpSuperHTTPServer for plain http mode is 3 minutes.
you can change it via setting IdleTimeout in OnManualBindSocket event:

procedure TServerForm.ROServerManualBindSocket(Sender: TObject);
  //should be before SocketX.Bind!
  TIPAsyncHttpServer(Sender).IdleTimeout := 6*60;  //  6 min

  // begin - this code block is required !
  if TIPAsyncHttpServer(Sender).BindV4 then
  if TIPAsyncHttpServer(Sender).BindV6 then
  // end

(RemObjects) #18

bugs://77876 got closed with status fixed.

(EvgenyK) #19

I’ve added SocketTimeout property to TROIpSuperHTTPServer . (#77876)
fix will be in next beta

(Lagarrigue, Frederic (Reigate)) #20

I tried changing the idletimeout in the OnManualBindSocket event, but still timeout just after 3 minutes. Is that something that is fixed with the SocketTimeout property?

(EvgenyK) #21

SocketTimeout provides access to IdleTimeOut like

procedure TROIpSuperHTTPServer.SetSocketTimeout(const Value: integer);
  fSocket.IdleTimeout := Value;

function TROIpSuperHTTPServer.GetSocketTimeout: integer;
  Result := fSocket.IdleTimeOut;

try to set timeout before binding like

procedure TServerForm.ROServerManualBindSocket(Sender: TObject);
  TIPAsyncHttpServer(Sender).IdleTimeout := 500;
  if TIPAsyncHttpServer(Sender).BindV4 then
  if TIPAsyncHttpServer(Sender).BindV6 then
end; (30.2 KB)

(Lagarrigue, Frederic (Reigate)) #22

yes that worked. I just added a dummy method that pauses for an amount of time. It was failing at about 3 minutes, but setting the timeout before the bind worked. The ultimate goal is to not have methods that take so long, but this is a gradual process.

Thanks for your help.