The subject of .net remoting can be very complex. There are several different ways you can do remoting; you can marshall by value or by
reference, you can use server-side activation or client-side activation. You can choose
SingleCall or Singleton instantiation, among
others. You can use either of the default protocols (tcp or http) or you can use a custom protocol.
In this article I’m going to attempt to give you, the reader, the most “bang for
your buck”. In other words, I’m going to use a configuration
which I believe addresses the majority of situations you are likely to encounter, and I’m going to strip away everything that’s unnecessary
for this configuration. (It’s sort of an 80/20 thing, if you change 80/20 to about 90/10.)
The scenario we’ll look at is one where we marshall by reference, use server-side activation, and Singleton instantiation.
The implementation I use will work equally well for either TCP or HTTP
protocols. In addition, I’ll show you
how to make everything configurable so that you can change either the client implementation or the server implementation on the fly, without
having to change any code or recompile.
This article is meant to be a quick tutorial to get you up and running quickly. I’m not going to go into any lengthy explanations about what
remoting is, or when and why you should use it other than to say that its best used when you need to communicate internally behind your
firewall, between applications/servers hosted on the same platform. In other words, you can’t use .net remoting to communicate between a
.net application and a java application, or over the internet. If you want more in depth information in that regard, there’s a ton of it on
Microsoft’s web site.
A Little Background
Our example will consist of three separate components. We will create these components in Visual Studio 2008 as three separate projects
within one solution.
The first of the three projects will be named ServerApp. The ServerApp component will be the actual application containing your business
logic, which you want to be able to access remotely.
The second of the three projects will be named Listener. The Listener component will reside with the
ServerApp component on the remote
server. The Listener component must be running in order for the ClientApp component (see below) to be able to reach the
ServerApp component.
When the Listener is first started, it loads its App.config file (compiled to Listener.exe.config), and reads from it all the information it
needs to tell it how to open the communication channel, which formatter to use (tcp or http), which port to listen on, the object type and
assembly name of the ServerApp component, and how to instantiate it. It then opens the channel and listens on the specified port
accordingly.
The third project will be named ClientApp. Its App.config file (compiled to ClientApp.exe.config) will contain information telling it the
location and port of the Listener component, as well as the formatter to use (tcp or http) and how to instantiate the
ServerApp. When the
server is called, the ClientApp component uses this information to contact the
Listener and request an instance of the
ServerApp.
Incidentally, all code listings and references to code are in C#.
Let’s Do It
So, in Visual Studio, we’ll create a new solution called Remoting, and for now let’s just create the
ServerApp project and the Listener
project. (We’ll save the ClientApp project for later.)
Creating ServerApp
Create a new ClassLibrary project and name it ServerApp. Rename the default class from
Class1.cs to ServerClass.cs, then replace any
existing code in that file with the following:
As you can see, our business logic is pretty simple. Within the ServerApp namespace we create a class named
ServerClass. The class inherits
from MarshalByRefObject, which it must do in order to be remotely instantiated and marshalled by reference.
ServerClass has one method,
Captialize, which accepts one string argument. The class then takes that argument, converts it to upper case, embeds it in a string which
also contains the date and time and the location of the ServerApp component, and if no exceptions are raised along the way, returns that
string.
Creating Listener
Next we will create the Listener component. In Visual Studio, within the same
Remoting solution in which we created the ServerApp project,
create another new project. This one will be a Windows Forms Application, and we can name it
Listener.
Rename Form1.cs to FormListener.cs, and add a button to the form. Name the button
btnStop, and assign “Stop Server” as its Text property.
Double click anywhere on the form to load the code behind file. In the FormListener_Load event, copy the following code:
Examining the above code, we can see that the RemotingConfiguration.Configure() method loads all the configuration information from your
App.config file (we’ll get to that shortly), and loads ServerApp accordingly. The first argument being passed to it represent the name of the
config file to load, in this case “Listener.exe.config”. (Your App.config file will take this name when your application is built.) The
second argument is a boolean argument that tells the method whether to implement security or not. For our purposes we will not, so we pass
false. In order for this to compile, you will also need to add the following using statements:
Next, double click on the Stop Server button so that the btnStop_Click event is displayed. Then copy the following code into the event:
Next, we need to add the App.config file. In order for it to work properly, it needs to be created not as a regular text file, but as
follows:
- Right-click on the Listener project
- Click Add
- Click New Item
- Choose Application Configure File from the dialog box, making sure that the file is named App.config.
Open the newly created App.config file, copy the following code into it, and then save it:
Note that the channel element has a ref attribute and a port attribute. As illustrated,
the settings will cause the Listener to listen for a tcp request on port
1234. If you wanted to use http instead, you would just change the ref attribute to "http".
Finally, build the entire solution. Once everything is built, create a new directory on your hard drive called “C:\RemoteTest”. Into this
directory you will need to copy the following three files from your build:
- Listener.exe
- Listener.exe.config
- ServerApp.dll
Creating ClientApp
Now we’re going to create one more Windows Forms Application project in our Remoting solution, called
ClientApp. Next, we want to add a
reference to the ServerApp application. Right-click the newly created ClientApp project, click
Add Reference, and in the Add Reference dialog box, click
the Browse tab. Browse to “C:\RemoteTest\ServerApp.dll”, and choose it. Note: Be sure to reference this dll, and not the
ServerApp
project.
Next, rename Form1.cs to FormClient.cs. Then add a text box and two buttons. Name the text box
txtData, and name the two buttons btnSubmit and btnExit. Open the code-behind file and add the following using statements:
Next, add the following class level variables:
Next, double-click anywhere on the form so that the FormClient_Load event is displayed. Then copy the following code into that event:
Looking at the above code, we can see that the RemotingConfiguration.Configure() method loads the
ClientApp’s App.config file, known as
ClientApp.exe.config after the build. If successful, an instance of ServerClass is instantiated.
Next, double-click on the btnSubmit button and copy the following code into the btnSubmit_Click event:
Next, double-click on the btnExit control so that the btnExit_Click event is displayed, and copy the following code into it:
Next, we need to add the client’s App.config file. In order for it to work properly, it needs to be created not as a regular text file, but
as follows:
- Right-click on the ClientApp project
- Click Add
- Click New Item
- Choose Application Configure File from the dialog box, making sure that the file is named App.config.
Open the newly created App.config file, copy the following code into it, and then save it:
Note that the client side config file is slightly different from the server side config file. This is the way it should be. When we test
the client, the url in the config file will point to the server localhost. If you eventually install the
ServerApp and Listener components
on a different machine, you will need to change the server name accordingly so that it points to that machine.
Note also that if you wanted to use http instead of tcp, you would need to change the
channel
element's ref attribute, and the wellknown element's url attribute accordingly.
Now you can build your ClientApp project.
Putting It All Together
In order to test all of our components, perform the following steps:
- Close Visual Studio.
- Go to C:\RemoteTest, and run Listener.exe
- Run your ClientApp.exe
- Enter any text into the ClientApp’s text field
- Click the Submit button
You should see a message box containing the string returned from the server, which should include an upper case version of the text string
you entered, the date and time, and the directory in which the ServerApp component resides.
I hope that this article sheds some light on an otherwise sometimes convoluted topic. Microsoft’s web site contains much more information on
.net remoting if you want to find out more.
Dave Verschleiser
Murray Hill Technologies