.NET remoting target refusing a single call - returns socketexception

269 Views Asked by At

I have an old school .NET remoting app that I needed to extend a little. As part of that, I brought it to .NET 4.0. (was .NET 2.0 before) The interface that is hosted looks like this

    public interface IRemoteSupportVM
    {
        string runAnOperation(Customer cust, List<CustomRoute> routes);

        string runAnotherOperation(string customer, string routes);

        string runAThirdOperation(List<string> pathsToBeCleaned);

        string writeFile(string path, string filename, int type, byte[] data);

        string readFile(string path, string filename, out byte[] data);

        string deleteFile(string path, string filename);

        long ping();
    }

ping, readFile, writeFile and deleteFile work just fine. When I call runAnOperation/runAnotherOperation/runAThirdOperation, I get an immediate SocketExcepting telling me

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

Now I now that's a bunch of baloney because all the other calls work just fine, and, the target does get the call and performs its thing. But since the client thinks the call failed, everything that comes after calling connect fails too.

the solution has a bunch of other remoting interfaces, and as far as I can tell, they all work except these two method calls. Any idea what could trip up the .NET remoting caller?

@edit: I noted another thing: the run* operations take a while to complete. The other operations return immediately. As I have the code of both sides of the remoting interface, I set a breakpoint on the implementation of ping(), and now I also get a SocketException when the client calls ping. So it seems to be a timeout I'm not aware of.

1

There are 1 best solutions below

0
Stephan Steiner On

Okay, so after a painful trial & error period, I finally found the culprit. It's the timeout of the channel when it gets initialized. That's how it was in the remote side code:

            IDictionary props = new Hashtable
            {
                ["port"] = config.Port,
                ["timeout"] = config.RemotingTimeout,
            };
            var channel = new TcpChannel(props, clientProv, serverProv);

Now it appears that the timeout property had no effect on .NET 2.0 - there's quite a few google results towards that effect. However, in .NET 4.0 it suddenly seems to take. Every remoting call is wrapped IAsync* Begin/EnvInvoke to ensure a result after the desired timeout (even if that result is that the server didn't provide a result in time). So either nobody every noticed that timeout had no meaning or the execution wrapper was put in place for exactly that reason (the software was started 15 years ago.. so who knows).

As config.RemotingTimeout was 70, a call had 70 miliseconds to complete or I'd get the SocketException. When I converted the 70 seconds (that I was expecting) to milliseconds ( so timeout = 70000), things suddenly started working the way I expected them to.