.NET Remoting: The Simplest Remoting Example

August 24, 2007 at 10:18 pm 2 comments

I just read chapter 10, .NET remoting, in Introducing Microsoft .NET 3rd Edition, 2003, by David S. Platt. His explanations are very clear and easy to read, but I had a little trouble compiling and running the sample code. Part of the problem is that the code was written for an earlier version of Visual Studio and the .NET library. I took notes as I upgraded and built this example and I thought I’d share them here. I built this example in Visual Basic 2005 Express SP1. I have upload this project into my Box.net folder on this blog. Even if you don’t have David Platt’s book you can probably get a good idea about how remoting works by looking at my VB2005 version of his example code, reading the introduction below,  and reading the on-line articles listed at the end of the introduction.


Introduction

I’m working on an application that can use two alternative user interfaces: a GUI, and a remote text terminal. Most of the time the application will be installed on a single computer and users will interact with the application through the Windows Forms GUI on that machine, and remote users will interact by sending text commands via TCP/IP. But there are also situations where users may wish to install the GUI on one machine and the application on another. In the old days, I would have solved this problem with DCOM. But, this is a .NET application, so I set out to learn the .NET way to solve this problem. (I made a decision at the beginning of the project to use .NET 2.0 rather than 3.0 or 3.5, since it is time tested and well documented.)

There are three general solutions available  in the .NET 2.0 Framework: ASP.NET (aka .NET web services, XML Web services), Enterprise Services (built on COM+), and .NET remoting. (With the introduction of Windows Communication Foundation in .NET 3.0 there are even more options.) You can read a good comparison of these methods in this MSDN Library article: .NET Framework Developer’s Guide: Choosing Communications Options in .NET. I chose .NET remoting because: 1) It doesn’t require IIS (or any other server). Our customer wouldn’t like the extra administrative overhead of having to set up and run an Internet server with this application. 2) Performance: .NET remoting over TCP or IPC gives better performance than .NET web services. 3) Preserves all the features of the managed code framework: the type system, pass by reference, etc.

There are three basic entities involved in .NET remoting: 1) The host- which just launches the remotable type. This will typically be housed in an .exe file. 2) The remotable type (class) – which runs in the application domain of the host, but presents it’s properties, methods, and events for consumption by a client in another application domain or on another machine. This is typically housed in a DLL. 3) The client- a class (usually housed in another .exe file) which instantiates an instance of the remotable type. The remotable type will appear as if it were running in this class’ application domain. You can read more about his in the MSDN article:  .NET Framework Developer’s Guide: .NET Remoting.

It is fairly simple to create each of these three entities:

  1. To create a remotable type, you only need to define a class that inherits the MarshalByRefObject base class. Here’s an example from the MSDN .NET Framework Developer’s Guide: How to: Build a Remotable Type.
  2. To create a host you need to do two things:
    – Create and register a server channel object, which will handle the networking protocols and serialization formats that transport requests to the remotable object.
    – Register the remotable type with the .NET remoting system so that it can use your channel to listen for requests for this type.
    Here’s an example from the MSDN .NET Framework Developer’s Guide: How to: Build a Hosting Application.
  3. To create a client you need to do three things:
    – Create a register a client channel.
    – Activate the remotable object. Depending on the activation mode you may be getting a reference to an object that was already created and published by the host, or you may be creating the object remotely.
    Here’s an example from the MSDN .NET Framework Developer’s Guide: How to: Build a Client Application.

Building and running the “SimplestRemoting” sample code
Here are the steps I took to build and run the “SimplestRemotingVB” code sample from Platt’s book:

1) Imported  the SimplestRemotingHostVB  project into VS2005 using the conversion wizard which starts automatically when you open a project created in a previous version of Visual Studio.

a) Changed the following declaration to use Dim instead of Public:

Dim Chnl As Runtime.Remoting.Channels.Tcp.TcpServerChannel
(Note that I am showing the line as it is after I fixed it, not as it was originally)

b) Added the argument true to the following line:

Runtime.Remoting.Channels.ChannelServices.RegisterChannel(Chnl, True)

c) Deleted the “AssemblyInfo.vb” file, since it isn’t needed.

2) Imported the SimplestRemotingObjectVB project into VS2005.

3) Imported the SimplestRemotingClientVB project in to VS2005.

a) Added the argument true to the following line:

Runtime.Remoting.Channels.ChannelServices.RegisterChannel(Chnl, True)

 4) Delete all the existing files in bin/release/ and bin/debug/. (I did this after I had trouble with the VB2005 “rebuild” command. Sometimes it didn’t recreate all the executables.)

5) Build each project.

6) Run the host, SimplestRemotingHostVB.exe, and click the “Register” button. You may have antivirus or other security software that will try to block the remoting host from opening a TCP port. If this happens you may get a pop-up message that gives you the option to allow this program to open a port. (Norton does this.)

7) Run the client, SimplestRemotingClientVB.exe, and click the “Register” button, and then the “Get time” button. You should see your computer’s time displayed.

Discussion

I would have called this section FAQs, but these are just my questions, but often my questions are also other people’s questions too, so I’ll pass them on with the answers I found.

  • Q: Do I need to run a web server like IIS, or apache in order to use a TCP channel with .NET remoting?
    A: No.
  • Q: How do I know I’m really creating a remote object (i.e., an object that really is in the host’s application domain and not in the client’s?)
    A1: Try running the client without first running the host and registering the remoting object. The client will throw an unhandled exception when you click on the “Get time” button. This doesn’t completely answer the question, but at least you know that the host is providing something that’s needed by the client.
    A2: Run the client in the VS2005 debugger. You will not see trace messages from the object in the immediate window. You will see trace messages when you run the host in the VS2005 debugger. Presumably the trace listener will not receive trace messages across a process boundary (or application domain?) so you only get trace messages in the host’s process since that is where the object is actually running.
  • Q: Is the DLL which houses the remoting object loaded by both the host and the server?
    A: Yes, if you look at the host and server processes in a process viewer like ProcessExplorer, you see that SimpleRemotingObjectVB.dll is loaded into both processes. Apparently this is because it is running in the host process and it is loaded in the client process because the client reads meta-data from it.

Building and Running the ConfigFile Sample Code

There is another example program in chapter 10 of Platt’s book, in the section titled “Big Simplification: Configuration Files”. I imported and built these files, but I wasn’t able to get the client to work using the configuration files. I’ve added this VB2005 project to my Box.net folder, just in case one of you can help me figure out why it doesn’t work. Here are the symptoms:

  • Everything builds without errors or warnings.
  • The host runs and throws no exceptions when I click either of the buttons (the top button registers the remotable object programmatically, the bottom button registers it using the app.config file.)
  • The client runs and throws no exceptions when I click the top button to register the remotable object using the app.config file. When I click the “Get time” button the application freezes.
  • I commented out the client code that does configures the client using the app.config file and replaced it with code that programmatically configures the client. Everything works with this code. My conclusion is that the host code that uses app.config is working, but there is something wrong with either the client app.config file or the code that registers it.

Any suggestions as to why this isn’t working?

Further Reading
Here are some additional articles that you may find helpful:

From MSDN
2007, The MSDN Library, .NET Framework Developer’s Guide: .NET Framework Remoting Overview
Matt Travis, 2005, What’s new in .NET Remoting for the .NET Framework 2.0 (Video)
Web Services and Other Distributed Technologies, Reference: .NET Remoting (Links to MSDN resources on remoting)

From the CodeProject
(These three articles have code examples in C#)
Nishant Sivakumar, 2002, Absolute Beginners Introduction to Remoting
Lim Bio Liong, 2004, Simple but Potentially Useful .NET Remoting, Part 2
2007, Remoting Architecture in .NET

From Developer.com
Paul Kimmell, 2004, .NET Remoting and Event Handling in VB.NET, Part 2, Part 3
(This article is very helpful and informative. I was able to build and run the example in VS2005 on Vista.)

From The SecretGeek
2003, .NET Remoting: The Quick and Dirty Guide

From VB.NET Heaven:
2004, .NET Remoting Using VB.NET

From “Welcome to the Metaverse”
Rich Turner, 2004, On the Road to Indigo: Is .NET Remoting Dead? (The answer: no! But… )

Advertisements

Entry filed under: .NET, Remoting, Technology, Visual Basic. Tags: , .

Join me in studying for MCTS exam 70-536 More on Delegates and Events in VB 2005

2 Comments Add your own

  • 1. Scott Marcus  |  March 11, 2008 at 8:46 pm

    Every VB .NET project (no matter the type) uses “AssemblyInfo.vb”. This is not why your remoting example doesn’t work, but it is a bad idea and you should not have touched that file. There are a number of hidden files under the “My Project” node of the project in the Solution Explorer. These files are not meant to be used by the developer directly, rather they are automatically written to when you modify various project settings.

    Why did you add “True” to the RegisterChannel method. This indicates that you want secure remoting, which adds complexity you shouldn’t worry about until you can get basic remoting working.

    Reply
  • 2. Bahrom  |  March 11, 2008 at 9:11 pm

    Scott, thanks for your input. Note that I was attempting to build this solution(which was originally a VB.NET 2003 solution) in VB 2005. It appeared to me that VB 2005 does not use the Assemblyinfo.vb files that were used in VB.NET. Regardless, I wasn’t able to get the client to work with or without this file in the projects.

    I added True to the RegisterChannel method becuase this is the recommended default setting in the MSDN documentation (probably because they are trying to get everyone to write secure code.) But again, the client di’dn’t work without this setting either.

    If you are able to get this example to work please let me know! I would like to understand what is keeping it from working.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed


Bird’s Bits

Computers, software & the Internet

Recent Posts

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 41 other followers


%d bloggers like this: