Click here to Skip to main content
Click here to Skip to main content

Absolute beginner's introduction to remoting

, 4 Apr 2002
Rate this:
Please Sign up or sign in to vote.
Introduces .NET remoting and the use of asynchronous callbacks using simple code snippets

Introduction

Remoting allows you to work with objects remotely. It is a lot more efficient than SOAP based web services but obviously it can only be used within intranets. On the internet you would have problems with firewalls, and an overall lack of security.

In really simple terms you have a client program running on a machine invoking functions on an object that is instantiated on a different machine. Let's jump into some really short and crisp code snippets. Usually I find that it's easier to understand a concept by looking at a small code snippet than if you read a 2000 word essay giving you all kinds of complicated theory. Of course any extra theory you learn is always going to help in a lot of ways.

The interface

The first thing we do is to create an interface called MyInterface. Then we'll compile it into a dll. Later we'll derive our remote class from this interface. Now, what this does for us is that on the client machine we can use this interface. Otherwise we'd have had to use the class directly from the client machine which pretty much makes the whole exercise a little futile.

// csc /t:library MyInterface.cs

public interface MyInterface
{
    int FunctionOne(string str);
}

The object

Now that we have our interface ready, let's create our class which we will invoke from a remote machine. We derive this class from MarshalByRefObject and MyInterface. Any class derived from MarshalByRefObject allows remote clients to invoke it's methods, which is just what we are trying to do here.

// csc /t:library /r:MyInterface.dll RemoteObject.cs

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;

public class MyRemoteClass : MarshalByRefObject,MyInterface
{
    public int FunctionOne(string str)
    {		
        return str.Length;
    }
}

The server

Now, let's write our remote server.

// csc /r:RemoteObject.dll RemoteServer.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

public class MyServer
{
    public static void Main()
    {
        TcpChannel m_TcpChan = new TcpChannel(9999);
        ChannelServices.RegisterChannel(m_TcpChan);
        RemotingConfiguration.RegisterWellKnownServiceType(
            Type.GetType("MyRemoteClass,RemoteObject"),
            "FirstRemote",WellKnownObjectMode.SingleCall);
        System.Console.WriteLine("Press ENTER to quit");
        System.Console.ReadLine();
    }
}

First we create a TcpChannel object which we use to transport messages across our remoting boundary. As you can see, I have also selected 9999 as the TCP port to listen on. Now you can understand how this would cause a hell of a lot of problems with firewalls. We use ChannelServices.RegisterChannel to register our TcpChannel with the channel services. Don't ask me what exactly goes inside that function. All I could figure out is that if you don't register the channel, remoting won't work. Now we use RemotingConfiguration.RegisterWellKnownServiceType to register our MyRemoteClass object as a well-known type. Now this object can be remoted.

The first time I saw the huge function name, I thought it was some kind of joke. But then the .NET framework has thousands of functions and classes and thus I guess they didn't really have a choice. It's a lot better than calling it __rwkst(...), I guess. I am using the word FirstRemote here which will be used as part of the URL that the client uses to access the remote object. I specified the SingleCall mode here, which means a new instance is created for each remote call. I could have used Singleton in which case one object would have been instantiated and used by all connecting clients. I guess if this was an advanced article [which it is not] written by an advanced level programmer [which I am not], there would have been some explanation as to the differences between the two modes.

The client

Okay, now run your server on one of the machines. Now let's take a look at the client which can be run on the same or on a separate machine. I had to run it on the same machine for some complicated technical reasons. Well to be honest, the complicated technical reason was that I had only one machine at home.

// csc /r:MyInterface.dll client.cs

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

class MyClient
{
    public static void Main()
    {
        TcpChannel m_TcpChan = new TcpChannel();
        ChannelServices.RegisterChannel(m_TcpChan);
        MyInterface m_RemoteObject = (MyInterface)
            Activator.GetObject(typeof(MyInterface),
            "tcp://earth:9999/FirstRemote");
        Console.WriteLine(m_RemoteObject.FunctionOne("Nish"));
    }
}

Just as in the server, we have a TcpChannel object, though in this case we don't specify a port. We also use ChannelServices.RegisterChannel to register the channel. We use Activator.GetObject to get an instance of the MyInterface object. As you can see I have used the hostname 'earth' in my URL, as that's my machine's hostname. In your case you'd have to replace it with the name of the remote machine or it's IP address. The word 'FirstRemote' which forms part of the URL was what I had passed to RemotingConfiguration.RegisterWellKnownServiceType on the server. Now that I have got my object I can call its member functions. Well, that was not too difficult now, was it?

Asynchronous Callbacks

In our client we have used synchronous calls to the remote object. The problem with this, is that if the function takes quite a while to execute, our program hangs until the function returns. Of course you could start a worker thread each time you wanted to access a remote method, but isn't very efficient. And if by any chance you are passing shared data to the method and also getting some shared data back, you would have to take care of thread synchronization. The good news is that you don't have to do all that complicated stuff. You can use asynchronous callbacks.

// csc asyncclient.cs /r:MyInterface.dll

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Messaging;

class MyClient
{
    public delegate int MyDelegate(string s);
    public static void Main()
    {
        TcpChannel m_TcpChan = new TcpChannel();
        ChannelServices.RegisterChannel(m_TcpChan);
        MyInterface m_RemoteObject = (MyInterface)
            Activator.GetObject(typeof(MyInterface),
            "tcp://earth:9999/FirstRemote");    
        MyDelegate m_delegate = 
            new MyDelegate(m_RemoteObject.FunctionOne);
        m_delegate.BeginInvoke("Amazing", 
            new AsyncCallback(MyCallBack),null);
        System.Console.WriteLine("Press ENTER to quit");
        System.Console.ReadLine();
    }

    public static void MyCallBack(IAsyncResult ar)
    {
        int l = ((MyDelegate)((AsyncResult)ar).AsyncDelegate).EndInvoke(ar);
        Console.WriteLine(l);
    }
}

Here we have two delegates. Delegates are type safe function pointers. The first delegate is one we create called MyDelegate. We point this to the function we need to access from our remote object. Now we call the function BeginInvoke. The first parameter is the parameter we pass to the actual function. The second parameter is another delegate of the AsyncCallback delegate type. What happens now is that the remote function is called but control returns immediately and our program won't block. Later, when the remote object completes the execution of the function, our callback is called with an IAsyncResult parameter which encapsulates the results of an asynchronous operation on an asynchronous delegate. We use the AsyncDelegate property to get our delegate and cast it to MyDelegate and call EndInvoke on it to get the results of the remotely executed function. You must keep in mind that the remote function has already terminated and its termination has nothing to do with EndInvoke. EndInvoke simply gives us back the results of the operation.

Conclusion

I really do hope that the beginners who read this article have found this article useful. There is a lot more to remoting and if I do learn more stuff, I'll post more articles on it here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Nish Sivakumar

United States United States
Nish is a real nice guy who has been writing code since 1990 when he first got his hands on an 8088 with 640 KB RAM. Originally from sunny Trivandrum in India, he has been living in various places over the past few years and often thinks it’s time he settled down somewhere.
 
Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - blog.voidnish.com.
 
Nish loves reading Science Fiction, P G Wodehouse and Agatha Christie, and also fancies himself to be a decent writer of sorts. He has authored a romantic comedy Summer Love and Some more Cricket as well as a programming book – Extending MFC applications with the .NET Framework.
 
Nish's latest book C++/CLI in Action published by Manning Publications is now available for purchase. You can read more about the book on his blog.
 
Despite his wife's attempts to get him into cooking, his best effort so far has been a badly done omelette. Some day, he hopes to be a good cook, and to cook a tasty dinner for his wife.

Comments and Discussions

 
GeneralMy vote of 5 PinprofessionalAmogh Natu21-Aug-13 23:06 
QuestionThanks Nish PinmemberMbuku Ditutala12-Mar-13 14:12 
GeneralMy vote of 5 Pinmembertusharpal5-Jul-11 21:59 
GeneralMy vote of 5 PinmemberAmosW13-May-11 2:32 
GeneralMy vote of 5 Pinmembervermamay19-Apr-11 20:38 
GeneralMy vote of 4 Pinmemberpaulsasik12-Oct-10 9:16 
QuestionNeed detailed description.... Pinmembersssabi3-Aug-08 2:55 
Hi,
I need the detailed description of the .Net Remoting Project. I searched in net, but i can't get the exact.It'll be good if anyone gives the step by step description of 'How to made .Net Remoting project with one example'. I tried this code, but no idea abou the tcp address and others.
Please help me to do the same.
 

Regards,
Satheesh
 
sa

Generalwireless internet Pinmembergw chuang1-May-08 21:01 
GeneralProblem with serialization of the client PinmemberJohn Kiley11-Mar-08 23:01 
GeneralGood Pinmemberdzlwgzs27-May-07 22:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140709.1 | Last Updated 5 Apr 2002
Article Copyright 2002 by Nish Sivakumar
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid