.Net Remoting: the Quick and Dirty Guide
secretGeek .:dotnuts about dotnet:.
home .: about .: sign up .: sitemap .: secretGeek RSS

.Net Remoting: the Quick and Dirty Guide

Are you studying for Exam 70-310 for MCSD or MCAD? Or has .Net Remoting given you The Fear?

The topic is much much easier than you think, so after studying the .Net Remoting section of Mike Gunderloy's excellent book (MCAD/MCSD Training Guide [70-310]) I've written a Quick and Dirty guide on the topic.

.Net remoting is a way of allowing two chunks of code talk to each other: across the room or across the world.

The first misconception to overcome is, as my boss put it 'But isn't that just Web Services?'

In short, while Web Services are Interoperable with many software vendors, languages and platforms, .Net remoting is Microsoft-Specific, and pretty much .Net specific as well.

And While Web Services must use Http, .Net remoting can use Http or Tcp, and it can be formatted as Binary or Soap. As such they can get a large performance boost over Web Services. Though I'd say they are trickier to write.

Why use .net remoting?

The reasons for .Net remoting are many, but they boil down to:

  1. You want to take a processing/memory load off the client's machines.
  2. There's hardware specific stuff that the clients can't do (e.g. you might have a Megatron Particle Accelerator and you want clients to be able to operate it. .Net remoting is your man!)
  3. You want to share data amongst a large number of clients. (e.g. you want clients to be able to look up data on your EmployeeGenePool database, without them having to individually host that database)
  4. You want your clients to be able to call some of your secret proprietary functionality but you don't want to give them the modules that perform this functionality. (And other control related reasons)
  5. You want to avoid redeploying your objects each time their functionality changes.
  6. Other. There's always an other.

So how do you go about it?

There's just a few important considerations really and after that it's just plug and play.

  1. Choose a Channel protocol. eg Tcp, Http.
  2. Choose a Formatter. eg, Soap, binary.
  3. Choose an Activation technique (ie choose an 'Architecture')
    1. Server activated (singlecall or singleton) (this is referred to as a WellKnown service/client type)
    2. Client activated (this is referred to as an Activated service/client type)

Implement .net Remoting in five minutes!

  1. On the Server:
    1. Create a Remotable Class
    2. Register a New Channel
    3. Register the Remotable Class
  2. On the Client
    1. Register a New Channel
    2. Register the Remotable Class
    3. Instantiate (and use) the Remote Class!

Alrighty. I'll go through each of those steps one at a time, and show you how it's done for each type of channel and activation.

Namespace warning: The following code assumes you've imported these namespaces (as required):

Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Http and/or:
Imports System.Runtime.Remoting.Channels.Tcp 

On the server: Create a Remotable Class

First, create a Remotable Class. This is the class that your clients are going to be using.

A remotable class looks like any other class except it Inherits MarshalByRefObject. Also, the only constructor it has is the default constructor ("Public Sub New()"), unless it is Client-Activated, in which case it can have overloaded constructors

Class Person
  Inherits MarshalByRefObject
  
  'Example property
  Private _Name As String
  Public Property Name() As String
    Get
      Return _Name
    End Get
    Set(ByVal Value As String)
      _Name = Value
    End Set
  End Property

  'The default constructor
  Public Sub New()
  End Sub

  '** Can only use this Overloaded Constructor if
  '   the class is going to be client activated!
  Public Sub New(ByVal pName As String)
    _Name = pName
  End Sub
End Class

On the Server: Register a New Channel

We're going to write some Channel Registration code.

The following code can sit in the same project as your Remotable Class. That's the easiest way to do it - but not a good method if you're looking at remoting a lot of classes.

So preferably your Channel Registration code will sit in a separate project that acts as a "Remoting Server." The Remoting Server project will need to have a reference to the project that contains the Remotable Class.

(In practice your remoting server wouldn't have a reference to the remotable class, but rather a reference to an interface implemented by the remotable class. See the Extra Credit topic below for more on this practice.)

Where was I? Registering a new channel on the server. Here goes. For TCP do this:

  'Register a New TCP Channel on port 1976
  Dim channel As TcpServerChannel = New TcpServerChannel(1976)
  ChannelServices.RegisterChannel(channel)

For HTTP do this:


  'Register a new HTTP server channel on port 1976
  Dim channel As HttpServerChannel = New HttpServerChannel(1976)
  ChannelServices.RegisterChannel(channel)

On the server: Register the remotable class

For server activated (i.e. WellKnown) do this:

  '**For SingleCall:
  RemotingConfiguration.RegisterWellKnownServiceType(GetType(Person), _
       "Person",  WellKnownObjectMode.SingleCall)

  '**For Singleton:
  RemotingConfiguration.RegisterWellKnownServiceType(GetType(Person), _
       "Person", WellKnownObjectMode.Singleton)

For client activated (ie, 'Activated') do this:

  'Register the client activated object
  RemotingConfiguration.RegisterActivatedServiceType(GetType(Person))

On the client: Register a New Channel

Note that the client code is similar to the host code, but you don't have to specify the port number (the host looks after this!)

For TCP channels...

  'Register a new TCP client channel
  Dim channel As TcpClientChannel = New TcpClientChannel()
  ChannelServices.RegisterChannel(channel)

For HTTP channels...

'Register a new HTTP client channel
Dim channel As HttpClientChannel = New HttpClientChannel()
ChannelServices.RegisterChannel(channel)

On the client: Register the Remotable Class

Warning! This requires that the client project has a reference to the project containing the Remotable Class. Usually this is not only a security risk, but completely impractical. Instead the client project could reference an Interface implemented by the Remotable Class. See the Extra Credit section for further details.

Assuming we've established a reference to the remotable class (or an interface it implements), we are ready to Register the client's with the remoting server.

If it's a ServerActivated (i.e. 'WellKnown') type:

  RemotingConfiguration.RegisterWellKnownClientType( GetType(Person), _
         "tcp://localhost:1976/Person")

If it's a Client Activated (i.e. 'Activated') type:

  RemotingConfiguration.RegisterActivatedClientType( GetType(Person), _
    "tcp://localhost:1976")

On the client: Instantiate (and use) the remote class!

Now we can finally access the remotable class from the client. Before we proceed, let's take a moment to appreciate the technical marvel that is .Net remoting.

Somewhere out there, on the other side of the world perhaps, a class sits on a server. The class inherits MarshalByRefObject and it has been registered with a remoting server. Out here, on the client machine, we've fired off a message to tell that remoting server we wish to use the remotable class. Now, the way is cleared and we are able to use that class here on the client as if the code were held locally. Time and space are no match for .Net.

So let's invoke the server-hosted remotable class from the client.

The following works for all types of remote objects:

  Dim lPerson as new Person()
  
  'Now do something with the object...
  lPerson.Name = "Fred"
  Messagebox.Show("Hello " & lPerson.Name)

In the case of Client Activated objects, you also get the ability to call Non-default constructors, for example:

  Dim lPerson as new Person("Fred")
  Messagebox.Show("Hello " & lPerson.Name)

Extra Credit: Create an Interface for your class

In the infamous 'Real World' you can't allow the client to reference your server-side remotable class.

(Two sufficient reasons for this: If your class implements Secret Business Formulae then you don't want your client to decompile them, and secondly for versioning reasons you don't want to be blatting your remotable classes out to clients every time you make a change.)

Instead you create an interface, bundle that into an assembly and let the clients reference the interface assembly. Try decompiling *that* suckers. You won't find out a thing about our Secret Business Formulae! Your Remotable Class sits safely tucked away on the server, happily implementing the published interface.

Here's our example. First an interface, that will be made available to any clients:

Public Interface IPerson
  Property Name()
End Interface

Now we change our remotable class so that it implements the IPerson interface:

Class Person
  Inherits MarshalByRefObject
  Implements IPerson
  Private _Name As String
  Public Property Name() As String Implements IPerson.Name
    Get
      Return _Name
    End Get
    Set(ByVal Value As String)
      _Name = Value
    End Set
  End Property
  Public Sub New()
  End Sub

  '** This Overloaded Constructor
  '   cannot be called from an interface!
  '   (nor from a server activated instance)
  Public Sub New(ByVal pName As String)
    _Name = pName
  End Sub
End Class

On the client side replace all instances of 'Person' with 'IPerson' and you are then able to create the object without having a direct reference to it (only a reference to the interface it implements)

But this creates a new limitation for Client-Activated objects. The interface can't include constructors. So we can no longer call our non-default constructor. This is a real annoyance if you are into Non-Default Constructors. And you should be. In order to get around this limitation, Mike Gunderloy suggests we use a special pattern: The Class Factory.

Create an Interface to a Class Factory

A "Class Factory" is just a term used to describe a Class that creates and returns other classes.

Create a ClassFactory with one method for each of the constructors you want to call in your remotable class. In the example above we'd have an interface called IPersonFactory, which implements two methods: one for the default constructor and one for our overloaded constructor.

Public Interface IPersonFactory
Function CreatePerson()As IPerson
Function CreatePerson(ByVal pName As String)As IPerson
End Interface

Now create a remotable implementation of the IPersonFactory interface

Public Class PersonFactory
  Inherits MarshalByRefObject
  Implements IPersonFactory

  Public Overloads Function CreatePerson() As IPerson Implements IPersonFactory.CreatePerson
    Return New Person
  End Function

  Public Overloads Function CreatePerson(ByVal pName As String) As IPerson Implements IPersonFactory.CreatePerson
    Return New Person(pName)
  End Function
End Class

The Person Factory will act as a Server-Activated (i.e. WellKnown) singleton - because a single long-lived instance of it can be used to return as many Person objects as the clients desire.

On the client you create an IPersonFactory and use it to return the IPerson object you're after.

Conclusion

If you kept up with all that then bully for you. Mike's book gives a much better coverage, but takes seventy or so pages to cover what we've just covered. In the same chapter he also touches on using 'SoapSuds' to generate proxy classes, using IIS as the activation agent (rather than writing your own remoting server as we did), Leasing, Marshal by Value (explicit Serialization) and much more. I guess it's time to move on, I'd better get out the book and keep studying...


Add or view comments about this page

Articles

The Movie Hollywood (And My Wife) Doesn't Want You To See: Weekend at Jacko's The Movie Hollywood (And My Wife) Doesn't Want You To See: Weekend at Jacko's
Sysi: the ultimate administrators toolkit Sysi: the ultimate administrators toolkit
Movie: Priest Academy Movie: Priest Academy
Inspirational Rat Story Inspirational Rat Story
A face-melting DSL that allows programming ON the iPhone (and iPad) A face-melting DSL that allows programming ON the iPhone (and iPad)
The secretGeek Disaster Recovery plan The secretGeek Disaster Recovery plan
Save KNVTn! Before it's too late Save KNVTn! Before it's too late
The Ultimate Agent of WERF Destruction The Ultimate Agent of WERF Destruction
The new prisoner's dilemma The new prisoner's dilemma
Original Premise for a road movie Original Premise for a road movie
What's a better game than Devshop? What's a better game than Devshop?
DevShop: The Cool Game that Makes Development Look Fun DevShop: The Cool Game that Makes Development Look Fun
Should be purple Should be purple
Kitchen Agile Kitchen Agile
Perhaps Perhaps "Go" is the new Visual Basic
zen-coding: turn those CSS selectors upside down zen-coding: turn those CSS selectors upside down
Debugging: It's all about finding Albuquerque. Debugging: It's all about finding Albuquerque.
The Real-Time online JQuery Editor The Real-Time online JQuery Editor
HTML5, a 3 minute guide HTML5, a 3 minute guide
Developer Codpieces Developer Codpieces
Agile for one: The Personal Story 'Wall' In Action Agile for one: The Personal Story 'Wall' In Action
Never work with thick people. Never work with thick people.
Cosmo: project status panel Cosmo: project status panel
Windows Search in Japan Windows Search in Japan
Project Management Zen Project Management Zen
Continuous Integration, Plugins and Going Too Far Continuous Integration, Plugins and Going Too Far
The Rules of Stand Up The Rules of Stand Up
Sydney International Airport: Stupid, Criminal, or Criminally Stupid? Sydney International Airport: Stupid, Criminal, or Criminally Stupid?
God No! ...The ReBuilder God No! ...The ReBuilder
Matt, The Office Mortar Matt, The Office Mortar
'Outlook style' rules for Subversion 'Outlook style' rules for Subversion
Really deep linking: Url + regex Really deep linking: Url + regex
hExcel -- A Hexagonal Spreadsheet hExcel -- A Hexagonal Spreadsheet
Is the remote control a thing of the past? Is the remote control a thing of the past?
The Utterly Thorough Guide To Awesome Application Compatibility on Windows 7. The Utterly Thorough Guide To Awesome Application Compatibility on Windows 7.
Astounding Hyperlinked Noticeboard Astounding Hyperlinked Noticeboard
Three Questions About Each Bug You Find Three Questions About Each Bug You Find
Recursing over the Pareto Principle... Recursing over the Pareto Principle...
Sometimes, The Better You Program, The Worse You Communicate. Sometimes, The Better You Program, The Worse You Communicate.

Archives .: secretGeek :: Complete Archives
TimeSnapper -- Automated Screenshot Journal TimeSnapper.com    
Version 3.3: true productivity boost

Next Action NextAction
Managing the top of your mind

World's Simplest Code Generator (html edition) World's Simplest Code Generator

25 steps for building a Micro-ISV 25 steps for building a Micro-ISV
3 minute guides -- babysteps in new technologies: powershell, JSON, watir, F# 3 Minute Guide Series
Universal Troubleshooting checklist Universal Troubleshooting Checklist
Top 10 SecretGeek articles Top 10 SecretGeek articles
ShinyPower (help with Powershell) ShinyPower
Now at CodePlex

Realtime CSS Editor, in a browser RealTime Online CSS Editor
Gradient Maker -- a tool for making background images that blend from one colour to another. Forget photoshop, this is the bomb. Gradient Maker


[powered by Google] 


How to be depressed How to be depressed
You are not inadequate.



Recommended Reading

The Best Software Writing I
The Business Of Software (Eric Sink)

Recommended blogs

Jeff Atwood
Reginald Braithwaite
Joseph Cooney
Phil Haack
Scott Hanselman
Julia Lerman
Rhys Parry
Joel Pobar
OJ Reeves
Eric Sink
Joel Spolsky
Des Traynor

Aggregated Links

programming.reddit.com
dzone
dot net kicks

Human Link Machines

interesting finds
a continuous learner's weblog
arjan's world
n links today
new and notable
morning coffee
learning .net
weekly link post
(my del.icio.us account)

LinkedIn profile
home .: about .: sign up .: sitemap .: secretGeek RSS .: © Leon Bambrick 2003 .: privacy

home .: about .: sign up .: sitemap .: RSS .: © Leon Bambrick 2003 .: privacy