Learn Programming

Introduction to .NET Remoting in C#

What is .NET remoting

.NET remoting is a technology that is part of the Microsoft .NET Framework that allows communication between programs over a network in a way that is easy to understand and hides all the complicated details of network communication.

How does remoting work

Remoting allows you to work with an object on a remote computer. The remote computer that hosts the object is called the server and the computer that accesses the remote object is called the client. The server uses remoting to make an object available to any clients that want to use it. The client connects to the remoting object on the server and is given a local copy of the server's object to work with. The thing about this local copy of the object is that any methods that are called on the object are executed on the server and the results are returned to the client. In other words the client has direct control over an object on a remote server.

If you want to create a remoting application then you need to first create the server that hosts the object. You then need to create the class with the methods that will be available to the client. Finally you need to use the remoting methods that are available in .NET to make the object available for clients to connect to.

After creating the server you create the client. The client must have a reference to the class of the remoting object in some way. The methods for remoting in .NET are then used to connect to the object that the server has made available. A reference to the object on the server is returned to the client and this is used just like an object in any normal program.

Creating the server

You need to create a new blank solution in Visual Studio called RemotingTest. Next you must add a Windows application project to the solution called RemotingServer. By default a form called Form1 is created but it will be easier to understand everything if we rename it to ServerForm. It is also a good idea to change the title of the form to "Server". This Windows application is just a simulation of a server and would probably be very different in a real project.

You must now add a new class to the project called MyRemoteClass. This will be the class that will be our remoting object. Make sure that the class is defined as public because it needs to be referenced by the client. All remoting objects need to inherit from MarshalByRefObject which means this one has to do it too. You need to add a method to the class called ShowMessage which will take a string as a parameter and then show the string using a MessageBox. The MessageBox title will be Application.ProductName so that we can make sure that the MessageBox is really coming from the server application. Here is the code for MyRemoteClass.

using System;
using System.Windows.Forms;

namespace RemotingServer
{
   public class MyRemoteClass : MarshalByRefObject
   {
      public void ShowMessage(string message)
      {
         MessageBox.Show(message, Application.ProductName);
      }
   }
}

We now need to make the class available to clients using remoting. First add a reference to System.Runtime.Remoting to the project. We are going to start remoting when the program starts by adding the remoting code to the Form Load event of ServerForm. A remoting application needs a TcpChannel to communicate through. This TcpChannel listens on a port for requests from clients. Here is the code to create a TcpChannel that listens on port 12345.

TcpChannel channel = new TcpChannel(12345);

Now that the TcpChannel has been created we need to register it with remoting. Here is the code to register the TcpChannel.

ChannelServices.RegisterChannel(channel, false);

The false parameter above is saying that the channel doesn't need to ensure security since this is just a test application. The last thing we need to do is register a well known service type or in other words register the class as available for use by clients. Here is the code to do that.

RemotingConfiguration.RegisterWellKnownServiceType(
   typeof(MyRemoteClass),
   "MyRemoteClass",
   WellKnownObjectMode.Singleton);

In the above code the RegisterWellKnownServiceType method is called. It takes 3 parameters. The first one is the type of the class that must be made available for remoting. The second is the name that it must be available as which is most often the same name as the class. The third one says in what way the clients must access the object. They can either access a new object every single time or use a singleton object which means that one object is created and used all the time which is much more efficient.

Make sure that you have referenced the following namespaces in the code of the form otherwise the program won't work.

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

The server is now complete and we can create the client.

Creating the client

Add another Windows application project to the solution called RemotingClient. Rename Form1 to ClientForm and change its title to "Client". Add a TextBox to the form called txtRemoteHost and set its Text property to "localhost". Add a Button to the form called btnConnect and set its Text property to "Connect". Add another Button to the form called btnShowMessage and set its Text property to "Show Message". Add a reference to System.Runtime.Remoting to the project just like you did for the server. Also add the remoting namespace references to ClientForm like you did for ServerForm otherwise the program won't work.

The TextBox is used to specify which server we want to connect to which will be important later when we test the program on 2 different computers but for now we will just be connecting to localhost.

The Connect button will connect to the server and get a reference to the remote object. You need to do all the following things in the Click event of btnConnect. The first thing it has to do is register a TcpChannel just like with the server.

TcpChannel channel = new TcpChannel();
ChannelServices.RegisterChannel(channel, false);

The next thing we have to do is set up the URI of the remote object which is a string that looks just like a URL address that you type into a web browser. Here is the format of the URI.

tcp://Server:Port/Class

We want our one to look like the following.

tcp://localhost:12345/MyRemoteClass

To do this we will create a string called uri that looks like the one above but we need to use our own server name from the TextBox on the form. Here is how we will create our uri.

string uri = "tcp://" + txtRemoteHost.Text + ":12345/MyRemoteClass";

You now need to add a reference to the RemotingServer project to the RemotingClient project. The reason for this is that MyRemoteClass only exists in the RemotingServer project and we need a reference to RemotingServer to be able to use the class. The other way of doing it is to use an interface but adding a reference to the project is a lot easier. After you have added the reference you need to create a module level variable of the type RemotingServer.MyRemoteClass called _MyRemoteClass. Make sure that you create it outside of any methods.

private RemotingServer.MyRemoteClass _MyRemoteClass;

Now go back to the Click event of btnConnect and add the following code.

_MyRemoteClass = (RemotingServer.MyRemoteClass)Activator.GetObject(typeof(RemotingServer.MyRemoteClass), uri);

What that does is get a reference to the remoting object of type RemotingServer.MyRemoteClass from the URI specified by uri. The reference is stored in the variable called _MyRemoteClass. Remember that even though _MyRemoteClass is declared on the client it is still referencing an object on the server.

Now we will add the code for the Click event of btnShowMessage. All we need to do here is call the ShowMessage method.

_MyRemoteClass.ShowMessage("Hello");

The last thing we need to do is go to the properties page of the RemotingTest solution and set both RemotingServer and RemotingClient to startup at the same time. You can now build the solution.

Testing it

When you run the program you should see a form for the server and a form for the client. Click the Connect button on the client form and then click Show Message. A MesageBox will show up that will say Hello and it will have the name of the server application to prove that it is really from the server.

The last thing you will want to try is copying the server to another computer and running it from there. Run the client from your own computer and set the TextBox to the name of the other computer and then test the program. If the computer that the server is running on has a firewall then you need to add an exception for port 12345 otherwise the client won't be able to connect to it. If you copy the client executable to another computer then make sure you copy the server executable with it because the client references MyRemoteClass which is in the server executable.