Mark Lidstone

Hi all,

This is a strange one I'm hoping someone can help with:

I have a service that marshals a single object via .net remoting. This is done so that clients can subscribe to events fired on the service.

When I only have one client, things work fine. However, if I try and use 2 or more clients at once, or if I connect a single client, close it, then run a second client I get the following exceptions when I try and use the events:

Requested Service not found

Failed to write to an IPC Port: The pipe is being closed.

Can anyone suggest where I need to go from here

Many thanks,

Mark Lidstone



Re: .NET Remoting and Runtime Serialization Multiple clients, events and disconnects

Christian Liensberger - MSP

The client has been disconnected without unsubscribing the event. We had that problem also with remoting.

We did walk around this by invoking each delegated method manually and remove the dead onces:

private void OnFoo(EventArgs e)

{

if (Foo == null)

return;

// Get the list of invoked methods!

EventHandler[] delegates = (EventHandler[])Foo.GetInvocationList();

// Loop backwards over them.

for (int i = delegates.Length - 1; i >= 0; i--)

{

try

{

// Try to invoke it.

delegatesIdea.Invoke(this, e);

}

catch (Exception)

{

// Remove the method if no longer valid.

// That's also why we loop backwards, makes removing easier.

Foo -= (EventHandler)delegatesIdea;

}

}

}

public event EventHandler Foo;

I hope this helps!






Re: .NET Remoting and Runtime Serialization Multiple clients, events and disconnects

Mark Lidstone

If only it were that simple :(

Here's the code we've been using:

lock (callbacks)
{
for (int nLoop = callbacks.Count; nLoop > 0; nLoop--)
{
try
{
callbacks[nLoop - 1](jobID);
}
catch (Exception e)
{
LoggingHandler.AddEntry(LOG_COMP, "Unexpected disconnect from client", e.Message, LoggingLevel.Normal);
callbacks.RemoveAt(nLoop - 1);
}
}
}

We've had to do this because we found that:

lock (eventList)
{
Delegate[] delegates = eventList.GetInvocationList();
for (int nLoop = delegates.Count; nLoop > 0; nLoop--)
{
try
{
delegates[nLoop - 1](jobID);
}
catch (Exception e)
{
LoggingHandler.AddEntry(LOG_COMP, "Unexpected disconnect from client", e.Message, LoggingLevel.Normal);
eventList -= delegates[nLoop - 1];
}
}
}

would remove *all* callbacks whenever "eventList -= delegates[nLoop - 1];" was called.

Attempting to call the invocation target that is no longer connected throws the exception as expected and we handle it by removing it from the list. The problem is that all the invocation targets seem to get messed up when that happens.

If I run the application with one client, close that client and try a second one, the second client receives no events. If I then close the second and open a third, that third one works fine (because all the callback lists are now empty).

Any ideas

Many thanks,





Re: .NET Remoting and Runtime Serialization Multiple clients, events and disconnects

Mark Lidstone

Something else I should have mentioned earlier, this happens when there have been no disconnections (all clients the server has seen are still live), and when the clients have actually disconnected properly (so their callbacks are not in the invocation list).

Many thanks,





Re: .NET Remoting and Runtime Serialization Multiple clients, events and disconnects

Mark Lidstone

OK, I finally figured out the cause : IPC

Our system attempts to connect using IPC if it's told to connect to the local machine. If not, it falls back to TCP, then finally to HTTP.

As I was running the client and server on my local machine, it was all going screwy. I turned off the IPC method and it works perfectly - multiple clients, disconnects etc....

Here's my code for the IPC setup on the server:

// Create and register the IPC channel
IDictionary ipcProps = new Hashtable();
ipcProps["portName"] = String.Format("localhost:{0}", endpoint.TCPPort);
ipcProps["name"] = String.Format("IPC_{0}_{1}_{2}_server", endpoint.Name, endpoint.TCPPort, endpoint.HTTPPort);
ipcProps["exclusiveAddressUse"] = "false";
IpcChannel icIPCServ = new IpcChannel(ipcProps, new BinaryClientFormatterSinkProvider(), m_bs);
ChannelServices.RegisterChannel(icIPCServ, false);

and the client:

IDictionary ipcProps = new Hashtable();
ipcProps["portName"] = "localhost:0";
ipcProps["name"] = "DotNetCommsClientIPC_" + Guid.NewGuid().ToString();
ipcProps["exclusiveAddressUse"] = false;
IpcChannel ipcChan = new IpcChannel(ipcProps, new BinaryClientFormatterSinkProvider(), m_bs);
ChannelServices.RegisterChannel(ipcChan, false);
oClient = (ICommsObject)Activator.GetObject(
typeToRequest,
String.Format(
"ipc://localhost:{0}/{1}",
endpoint.TCPPort,
endpoint.Name
)
);

Our temporary solution is to comment out the IPC methods so the system is forced to use TCP or HTTP instead, but I'd still appreciate some help with this one It looks either like something missing from the IpcChannel documentation, or a bug in the IPC channel implementation Or have I missed something

Many thanks,





Re: .NET Remoting and Runtime Serialization Multiple clients, events and disconnects

Christian Liensberger - MSP

Mark Lidstone wrote:
Something else I should have mentioned earlier, this happens when there have been no disconnections (all clients the server has seen are still live), and when the clients have actually disconnected properly (so their callbacks are not in the invocation list).

Many thanks,

This sounds familiar. We also lost from time to time the events. In out case this was due to network problems. For a millisecond there was no connection and all events were dead. We changed that and use polling for critical stuff, because the events over remoting just weren't reliable at all. We have found no other solution: events in Remoting are very very problematic. A firewall in the middle could also for example kill all the events. This won't apply during development, but could be on the customer's side - that's why we don't rely on them anymore.

What I have seen is that a guy has developed an advanced remoting solution: www.genuinechannels.com and he claims to have enhanced events and remoting in general.