0

I have a WCF service hosted in a Windows service which publishes errors to any subscribed monitor applications. There are 2 server applications which publish errors to the service and then these errors are sent to any subscribed monitor applications. This is done using WSDualHttpBinding.

This works but after a length of inactivity it stops working and brings up an error stating that the reliable session was faulted. I have read several articles on this issue but it hasn't helped track it down. I have put in all neccessary exception handling but this isn't helping.

Rather than post my code, the system is based on the List Based Publish Subscribe sample in the MSDN just with addition error checking and exception handling. Link below.

http://msdn.microsoft.com/en-us/library/ms752254.aspx

Does anyone have any ideas what is causing this?

Jonnster
  • 3,094
  • 5
  • 33
  • 45
  • is there nothing in the InnerException about what might be causing the issue? – Jethro Aug 25 '11 at 10:14
  • This seems to be caused by the inactivitytimeout setting? My connection is persession so why even have a inactivity timeout? In an ideal world, our server wouldn't be causing errors and therefore there would be nothing for the error service to report to the monitoring applications. I still want the connection to be open in case. Can the inactivity timeout be disabled completely? If not, is there a way of detecting that the connection was closed so it can be reopened? – Jonnster Aug 25 '11 at 10:33
  • So it seems to be a bug as mentioned here http://www.smartasses.be/2009/01/26/wcf-reliable-session-and-keep-alives/ The solution is to "ping" the monitor applications at a given interval. Seems really silly to me but there you go. Surely part of the point of a reliable session is to ensure the connection is alive for as long as required? – Jonnster Aug 25 '11 at 10:40

2 Answers2

1

You're right that you need to increase your inactivity timeout. But when you are using reliable sessions, the receiveTimeout is also taken into account. From this MSDN Article:

When using a reliable session, there are two different inactivity timers that must be satisfied to keep the connection alive. If either of these inactivity timers goes off, then the connection is dropped.

The first inactivity timer is on the reliable session and is called the InactivityTimeout. This inactivity timer fires if no messages, either application or infrastructure, are received within the timeout period. An infrastructure message is a message that is generated for the purpose of one of the protocols in the channel stack, such as a keep alive or an acknowledgment, rather than containing application data.

The second inactivity timer is on the service and uses the ReceiveTimeout setting of the binding. This inactivity timer fires if no application messages are received within the timeout period. This specifies, for example, the maximum time a client may take to send at least one message to the server before the server will close the channel used by a session. This behavior ensures that clients cannot hold on to server resources for arbitrary long periods.

Since the connection is dropped if either inactivity timer fires, increasing InactivityTimeout once it is greater than ReceiveTimeout has no effect. The default for both of these timeouts is 10 minutes, so you always have to increase both of them to make a difference when using a reliable session.

Setting both of these values to "Infinite" (if you're using config files) or TimeSpan.MaxValue if you're setting your bindings up in code should achieve what you're looking for.

EDIT 1 Setting the receiveTimeout and inactivityTimeout values to "infinite" will generate a warning in the compiler. This is okay. The IDE uses an XSL that doesn't take that keyword into account. Behind the scenes, WCF is using a TimeSpanOrInfiniteConverter to convert the keyword to TimeSpan.MaxValue. Source

villecoder
  • 13,323
  • 2
  • 33
  • 52
  • When I update the app.config so that the value is "Infinite" I get the warning that it is not valid value. So how do I set it to infinite? – Jonnster Aug 25 '11 at 13:23
  • I have set both timeouts to 24.20:31:23.6470000 (the maximum value that it seems you can set it to). It still times out after about 10 minutes of inactivity. – Jonnster Aug 25 '11 at 14:05
  • Edited my answer regarding the Infinite keyword. Can you post your binding configuration in your original question? – villecoder Aug 25 '11 at 20:46
0

I seemed to have fixed this but all I have done is change the binding from WSDualHTTPBinding to NetTcpBindng. It's now been running for 48 hours whereas before it wouldn't run for more than an hour.

Jonnster
  • 3,094
  • 5
  • 33
  • 45