0

tl;dr:

I'm trying to find where the .Net Remoting Framework runs (e.g., a service name or process name). Additionally, source would be amazing.

Context:

I'm maintaining legacy code that uses .Net remoting to allow the use of objects that store connection information between two processes, and which has long had problems with random disconnects and crashes apparently due to those remoting objects timing out. The issue we've seen is spoken about in the answer for this post, specifically the bit:

My issue was using the Marshal to register the remoting object. Over time the remoting object will disappear for clients to consume, i.e. no longer on the remoting object.

The approach to 'fixing' this we used in the past was what was mentioned in that post : returning a null lease manager, which keeps objects alive forever, in order to avoid the random unwanted timeout.

A few years ago, that code was removed due to it causing an issue on Linux - basically, each connection left alive after it was useful would consume a socket, and since sockets are files on Linux, we'd run out of file descriptors. As we thought the functionality that the timeout issue most affected had been deprecated, we reinstated regular timeouts, and everything was fine for two years.

Recently, however, a recent patch to Windows or some other environmental change seems to have caused the unwanted timeout issue to come back in full force on some of our machines (on Windows only; Mono seems to handle this workflow fine, giving me the strong hunch that it's a .Net bug). Specifically, any time we attempt to connect a new client after another client has maintained a connection for ~5 hours or more, the process hangs on trying to connect to a TCP port that, if I understand correctly, is what the Remoting Framework told us is where our server is listening.

As this cripples our Windows usage, it's resulted in this defect finally getting a push to be correctly solved, and what I'm trying to figure out now is why, after a period of time ~5 hours of constant connection from one client, we're no longer able to make remoting connections from a new client process to the server. But first, in order to do that, I want to understand the whole workflow, which includes knowing what's going on in the .Net Remoting Framework that stores the needed information for the remoting connection to be created in the first place. However, everything I've read just mentions the Framework in passing, not explaining what exactly it is.

Question:

Many different(PDF warning) articles on .Net remoting refer to the ".Net Remoting Framework" as being the critical piece that stores information about objects registered with either RemotingServices.Marshal or RemotingServices.RegisterWellKnownSericeType. If I understand correctly, it then allows other client .Net processes to query it for those objects using a URI that both processes know as a key.

Where is this process or service that gets queried? Honestly, even if the answer is something I've somehow missed clearly mentioned in the documentation, I would be ecstatic just for having it. Thanks!

(Also, of course, any additional insight on my greater problem would be appreciated.)

Edit: The 'greater problem' appears to be that a security software program we were running was interfering with the network adapters in our work machines, sometimes causing System.Net.Sockets.SocketExceptions to occur during our remoting program's attempt to connect through those sockets. This meant that when the LeaseManager went to check if a Lease was still working for a RemotingObject, it'd see a socket error and reflexively consider the Lease as disconnected, and as such drop the object reference we wanted kept alive. Our approach will be to return the InitializeLifetimeService function to be returning null, and handle all object garbage collection ourselves using the Dispose pattern. Full description is here.

Community
  • 1
  • 1
Marshall Conover
  • 855
  • 6
  • 24

1 Answers1

1

It runs wherever the application which defines a host in the configuration section, which can be IIS, a Windows service, or console application. The client application will need to have some configuration as well, to tell it that the class is really a proxy to a remoting host.

The types which are used in remoting are in the Sytem.Runtime.Remoting namespace.

I've never used remoting where I kept the object proxy alive for hours; I'd think you'd normally want to new one up, use it, then discard it. If that's not possible, check the mode. SingleCall is probably the best option, as on the host side a new object is created for each remoting request, and destroyed when done. Longer lived objects may have some stale state that hangs around if not coded correctly, or perhaps there's a memory leak or some other issue.

We still use remoting as well for a ClickOnce smart client, and we don't have the timeout issues you're encountering, but our remoting is configured for SingleCall only.

From the link, this would be the configuration in the hosting application:

<configuration>
  <system.runtime.remoting>
    <application>
      <service>
        <wellknown mode="SingleCall" type="Hello.HelloService, Hello" 
objectUri="HelloService.soap" />
      </service>
    </application>
  </system.runtime.remoting>
</configuration>

And this on the client:

<configuration>
  <system.runtime.remoting>
    <application>
      <client>
        <wellknown type="Hello.HelloService, Hello" 
url="http://localhost:8000/HelloService.soap" />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>
Andy
  • 8,432
  • 6
  • 38
  • 76
  • Thanks Andy! Your comment has lead me here: http://www.codeproject.com/Articles/29945/All-you-need-to-know-about-NET-Remoting, which is giving me some additional context. However, it seems our application doesn't have a system.runtime.remoting section in its configuration file. Do you know if there's a default service that's started up that the CLR somehow knows about if one is not specified by an application? – Marshall Conover May 19 '16 at 13:54
  • Additional note: We also don't use the other option mentioned, the RegisterWellKnowClientType. – Marshall Conover May 19 '16 at 14:01
  • Hi Andy! I'm going to ask in a separate question what the default configration is if you use neither the configuration file nor the RegisterWellKnownClientType function, and accept your statement of it running wherever the host defines for now. Thanks! – Marshall Conover May 19 '16 at 18:08
  • 1
    @MarshallConover I believe you can also use ChannelServices (https://msdn.microsoft.com/en-us/library/system.runtime.remoting.channels.channelservices(v=vs.110).aspx) to configure things. – Andy May 19 '16 at 22:20
  • @MarshallConover Oh, have you tried putting back the code to return a null lease manager? Perhaps that was a bug on the linux side which is now fixed. – Andy May 19 '16 at 22:31
  • Andy, I think that may be how we're doing it. Thanks for the hint! Also, sadly, it's not a bug on the linux side, just a bad usage pattern - the objects we'd never be collecting would be holding on to sockets, so the garbage collector would be correct in never closing the sockets, since those are managed resources. My current lead is that I noticed the finalizer being called on the LeaseManaged objects, and I'm thinking how we handle that may be the issue, since we don't want them being finalized at all until the connection ends, only once the connection is over. – Marshall Conover May 23 '16 at 14:24
  • Andy, if you want to point out the ChannelServices comment in this question: http://stackoverflow.com/questions/37331444/in-net-remoting-if-you-dont-specify-a-remoting-service-in-a-configuration-fil, I'll mark it as the accepted answer. Turns out we were registering a channel and passing the port of the client. Thanks again! – Marshall Conover May 25 '16 at 16:44