Automatic failover for two .NET remoting servers

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi!

I have an application written with Windows Forms. in C# that
uses remoting (http-channel, binary formatter) to talk to
the middle tier on a IIS6.
I now want to make the server more available by having two
servers which both have the remoting-server deployed. I don't
want to use clustering or round-robbing-DNS. The server has no
state.

I want to implement a sink or channel that is able
to catch exceptions that happen while remoting and is able
to switch over to the other server when the first server is
down.

Is there any sample code or pointer how to do it?

How can I get inside remoting above the http-transport and
how can I catch the exceptions from it and how can I have
two HTTP-channels below this to switch? Or is it possible
to change the properties of it on the fly and restart the
HTTP-communication?

Many thanks for your answers!
 
Hi Artmanaged,

Thanks for your posting.
As for the problem you mentioned, here are some of my suggestions:

Yes, the .net remoting has provide the intefaces for us to hook into the
channel sinks on both serverside or clientside to do some custom
processing. Here is a certain tech article discusing on such topic:

#Secure Your .NET Remoting Traffic by Writing an Asymmetric Encryption
Channel Sink
http://msdn.microsoft.com/msdnmag/issues/03/06/NETRemoting/default.aspx


But as my opinion, the when processing the exception occcurs at serverside,
we'll have to provide our customized clientside sink and try getting the
exception from the Message Object and try reidirect to another server. This
is a possible approach, but there'll have some particular conditions such
as when the certain server is unavailable, then maybe no such a exception
can be found in the returned message.

My suggestion is that we encapsulate the remoting object's calling at
client side. For example, we use a certain class to expose the methods that
call the remote object and in the methods, we can use
try....catch blocks to hold on any possible exceptions(clientside or
serverside) in the methods. Then, if on error, we can try request the
remote object from another remote server(querying the existing remote
server list from config file or from a remote service). And we can also put
all the available servers list in the clientsdie app's application config
file which can also be updated when there is a new remote server availabe.

Just some of my suggestions. If you have any other ideas , please feel free
to post here. Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
Hi!

Thanks for your suggestions.

I made much progress with my goal and have it working now.
The server part is not modified at all.
I don't use the backward-channel to my application,
all I have is one object from which I call all the methods. This
object has no state.

I created a clientsink and a IClientChannelSinkProvider.
My Clientsink is a messagesink and sits above the formatter.
It simply modifies the __Uri-Property to switch over after it
sees a message that has an Exception in it.
This is working quite nice, but I want a nicer interface for
my ClientChannelSinkProvider.
At the moment the failover-urls (several servers) are a property
of the ClientChannelSinkProvider which passes it on.

But I want to have my own protocol (e.g. swap:// ) instead of
http://

I tried in


public class SwapMessageSinkProvider : IClientChannelSinkProvider
{
public IClientChannelSink
CreateSink(System.Runtime.Remoting.Channels.IChannelSender channel,
string url,object remoteChannelData)
{
//here url is parsed and modified to be "http://..."
IClientChannelSink nextSink=next.CreateSink(channel,url,remoteChannelData);



to parse the url (string url) and get my information and pass on a
"http://xxx"-type-url downwards to the HttpChannel.

But it doen't work, I get an exception.

BTW: I don't use config-files for remoting-configuration, but the following
simple code instead:

IClientChannelSinkProvider formatter=new
BinaryClientFormatterSinkProvider();
SwapMessageSinkProvider swap=new SwapMessageSinkProvider();
swap.Next=formatter;
ChannelServices.RegisterChannel(new HttpClientChannel(dict,failover));

So I only use HttpClientChannel and the BinaryClientFormatterSinkProvider.
No HttpChannel, only HttpClientChannel. (I have seen samples like the
jabber-channel
which register their jabber://-protocol insinde the JabberChannel-Class, not
in
the JabberClientChannel-Class)

Why doesn't it work to modify the url that is passed downwards to the
HttpClientChannel?

If I try it I get an exception in the later

m_server=(IServer)
Activator.GetObject(typeof(IServer),"swap://xxx;yyy;zzz");

I think that I somehow must register my swap:// protocol somewhere??

Many thanks in advance for your answer!
 
Hi,

I am not very sure about how the client channel sink works. If it receives
a message with the exception, the exception has already occured at the
remoting server. What is the purpose for us to modify the URI? If we would
like to capture the exception at the client side, we can also capture it
with "try" block without involving the sink.

As far as your own protocol (swap://) is concerned, I think you need to
implement your own channel, like the TcpChannel or the HttpChannel. Then
you register the channel with the
"<configuration><system.runtime.remoting><channels><channel>" element or
ChannelServices.RegisterChannel method. In your client side channel, you
should implement the "IChannelSender.CreateMessageSink" method.

Regards,

Felix Wang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Back
Top