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

A simple Remoting HelloWorld

, 1 May 2005
Rate this:
Please Sign up or sign in to vote.
In this article, I will explain how to do remoting in VB.NET using Framework 1.1.

Sample Image - Remoting_HelloWorld.jpg

Introduction

Searching a lot, I didn't found a really easy remoting sample to show in the courses that I do, so I decide to publish my own article on how to do remoting in an easy way.

First of all, this article is based in VB.NET using .NET Framework 1.1 (Visual Studio 2003).

I will explain how can you do communication with components using Remoting, I will do a brief introduction to remoting now:

At old times, when application development started, we worked with COM, which allowed us to separate UI applications from functional libraries (DLLs). Later we received DCOM that allowed us to communicate between two different components in different computers. DCOM is a very proprietary RPC-based communication protocol for COM-based distributed component architectures. Even though DCOM allows us to create scalable and reliable architectures in the Intranet environment, there are a lot of problems with DCOM when you try to integrate it with different platforms and technologies in an Internet environment.

Now with the new .NET technologies, we receive WebServices and .NET Remoting. The web services allow us to communicate between different platforms and technologies, using standards HTTP and SOAP, that are very good, and very easy to implement. But web services lack some points when you want to work with State Management with .NET. Remoting provides support for both stateful and stateless environments through Singleton and SingleCall objects.

Talking about Type Systems Web services support only the data types defined in the XSD type system, limiting the number of objects that can be serialized, while .NET Remoting uses binary communication, providing support for rich type system. Of course that Web Services has some better points than .NET Remoting, as for example the Interoperability, providing support to interoperability across platforms (ideal for heterogeneous environments), while .NET Remoting requires the client be built using .NET.

Though both the .NET Remoting infrastructure and ASP.NET Web services can enable cross-process communication, each is designed to benefit a different target audience.

For applications that require interoperability and must function over public networks, Web services are probably the best bet. For those that require communications with other .NET components and where performance is a key priority, .NET Remoting is the best choice.

Now let's talk about our solution!! Because Remoting object will not be active by default, we need to create an Application Host Domain (this is how MS calls them), in order to load our exposed library in memory, and expose it as a Remote object. Our solution will consist of four projects, as follows:

  1. IRemoteLib: This will be a sample interface, that will be used by the client and the server part.
  2. LibraryExposed: is the IRemoteLib implementation and it will inherit from MarshalByRefObject, here are all the methods used by the client.
  3. EasyInvoke: This is a WinForm application (it's our Application Host Domain implementation) that will load LibraryExposed and will expose it to our client. We will instance our library as Server-activated object as Singleton activation (the difference in a singleton and single call lies in lifetime management. While single-call objects are stateless in nature, singletons are stateful objects, meaning that they can be used to retain state across multiple method calls. Singleton types never have more than one instance at any one time, sharing the same instance between all clients, while SingleCall types always have one instance per client request).
  4. ClientApplication: This is a WinForm application that will call the remote object.

Using the code

Now let's start with source code. First of all, we need to create our Interface (IRemoteLib).

Public Interface IRemoteLib


  ' This event will be used at server to inform every connection
  Event LibCalled(ByVal message As String) 

  ' Call to Hello World Method
  Sub HelloWorldMethod()

  ' Call to Hello World Function
  Function HelloWorld() As String

End Interface

Now let's continue with the implementation (LibraryExposed).

Public Class RemoteLib
  Inherits MarshalByRefObject
  Implements IRemoteLib
  Public Event LibCalled(ByVal Message As String) Implements IRemoteLib.LibCalled
    '---------------------------------------
  Public Function HelloWorld() As String Implements IRemoteLib.HelloWorld 
    RaiseEvent LibCalled("Call HelloWorld ")
    Return "Hello World"
  End Function
  Public Sub HelloWorldMethod() Implements IRemoteLib.HelloWorldMethod
    RaiseEvent LibCalled("Call HelloWorldMethod ") 
  End Sub
End Class

As you see everything is very easy, just pay attention at Inherits MarshalByRefObject. This is where we specified that this will be a remoting object. We do it this way, because we want to specify a singleton, and we want that the client access the remote object using a proxy class.

Now let's implement the EasyInvoke (because it's a WinForm, you need first to create a WinForm, just with a ListBox docked at it). This is the LibraryExposed remote object activation:

Dim objServer As IRemoteLib
Private Sub Form1_Load(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles MyBase.Load
  Try
    Dim ServiceChannel As IChannel
    Dim serverProv As BinaryServerFormatterSinkProvider = _
             New BinaryServerFormatterSinkProvider 
    Dim clientProv As BinaryClientFormatterSinkProvider = _
             New BinaryClientFormatterSinkProvider
    Dim Props As IDictionary = New Hashtable
    Dim IpInjProvider As New IpInjectorSinkProvider
    serverProv.TypeFilterLevel = _
        System.Runtime.Serialization.Formatters.TypeFilterLevel.Full
    Props("port") = "8000"
    Props("name") = "EasyInvoke"
    ServiceChannel = New TcpChannel(Props, clientProv, serverProv)
    '---------------------------------------------
    ChannelServices.RegisterChannel(ServiceChannel)
    RemotingConfiguration.RegisterWellKnownServiceType( _
                  GetType(RemoteLib), _
                  "EasyInvoke", WellKnownObjectMode.Singleton)
    lstConsole.Items.Add("RemoteLib Started as remoting") ' This is the listbox
    '----------------------------------------------------------
    Init() '--------->> this will be used to catch the events from remote object
  Catch ex As Exception
    lstConsole.Items.Add("Error:" + ex.Message)
  End Try
End Sub

This was how to register our LibraryExposed as a remote object. Now let's finish our server as an enhancement that will allow us to retrieve which client is connecting and which method is using our remote object.

'---------------------------------------------------------------
Private Sub Init()
  Dim server As IRemoteLib
  Dim Channel As System.Runtime.Remoting.Channels.tcp.TcpChannel 
  Dim serverProv As BinaryServerFormatterSinkProvider = _
         New BinaryServerFormatterSinkProvider
  Dim clientProv As BinaryClientFormatterSinkProvider = _
         New BinaryClientFormatterSinkProvider
  Dim props As IDictionary = New Hashtable
  serverProv.TypeFilterLevel = _
         System.Runtime.Serialization.Formatters.TypeFilterLevel.Full
  props("port") = 0
  Channel = New System.Runtime.Remoting.Channels.tcp.TcpChannel(props, _
              clientProv, serverProv)
  ChannelServices.RegisterChannel(Channel)
  Try
    server = CType(Activator.GetObject(GetType(IRemoteLib), _
             "tcp://localhost:8000/EasyInvoke"), IRemoteLib)
    If server Is Nothing Then
      MsgBox("server not found or bad initialized!")
    End If
    server.HelloWorldMethod()
  Catch ex As Exception
    Debug.WriteLine(ex.Message)
  End Try
  
  'This is where we say how to handle events from the remote object
  AddHandler server.LibCalled, AddressOf ReceiveLibCall 

End Sub
<System.Runtime.Remoting.Messaging.OneWay()> _
Public Sub ReceiveLibCall(ByVal message As String)
  lstConsole.Items.Add(message)
End Sub

Here we add an enhancement to our server side, just to listen the events from the remote object to display which method is in use by the client at our ListBox (lstConsole).

And now the ClientApplication implementation:

You should create a WinForm with three buttons, one connect button (butConnect), one HelloWorldSub button (butHelloWorldSub), and one HelloworldFunc button (butHelloWorldFunc) and add this code:

Private server As IRemoteLib
Private Channel As System.Runtime.Remoting.Channels.tcp.TcpChannel 
Private serverProv As BinaryServerFormatterSinkProvider
Private clientProv As BinaryClientFormatterSinkProvider
Private props As IDictionary = New Hashtable

Private Sub SetChannel()
  serverProv = New BinaryServerFormatterSinkProvider
  clientProv = New BinaryClientFormatterSinkProvider
  serverProv.TypeFilterLevel = _
      System.Runtime.Serialization.Formatters.TypeFilterLevel.Full
  props("port") = 0
  Channel = New TcpChannel(props, clientProv, serverProv)
End Sub
Private Sub Init()
  SetChannel()
  ChannelServices.RegisterChannel(Channel)
  Try
    server = CType(Activator.GetObject(GetType(IRemoteLib), _
           "tcp://localhost:8000/EasyInvoke"), IRemoteLib)
    If server Is Nothing Then
      MsgBox("server not found!")
    End If
  Catch ex As Exception
    MsgBox(ex.Message)
  End Try
End Sub

And now implement the buttons click:

Private Sub butHelloWorldSub_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles butHelloWorldSub.Click
  Try
    server.HelloWorldMethod()
  Catch ex As Exception
    MsgBox(ex.Message)
  End Try
End Sub
Private Sub butHelloWorldFunc_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles butHelloWorldFunc.Click
  Try
    MsgBox(server.HelloWorld)
  Catch ex As Exception
    MsgBox(ex.Message)
  End Try
End Sub
Private Sub butConnect_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles butConnect.Click
  If butConnect.Text = "Connect" Then
    Init()
    butConnect.Text = "Disconnect"
    butHelloWorldFunc.Enabled = True
    butHelloWorldSub.Enabled = True
  Else
    ChannelServices.UnregisterChannel(Channel)
    butHelloWorldFunc.Enabled = False
    butHelloWorldSub.Enabled = False
    server = Nothing
    Channel = Nothing
    serverProv = Nothing
    clientProv = Nothing
    butConnect.Text = "Connect"
  End If
End Sub

That's all folks! I hope you enjoy it!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Ricardo Fig
Web Developer
Spain Spain
Hi, I develop since I was 10 (ten) years old, I worked on Basic, QBasic, Pascal, Cobol, C, C++ until 17 years old, then I started my carear as Systems Engineer, and I started to do some MS exams, until I got the degree of Microsoft Certified Professional, in that year I got, MCP+Internet, MCSE, and MCSE+Internet and MCT, then I started to work with Java and I got SUN Java certifications also.
 
Working as developer I did a lot of differents types of applications (integration app, invoice systems, games, etc).
 
Also I have some knowlegde on SAP Systems, because I installed it and played it a little bit (SAP WAS 6.10, 6.20 and 6.30), in conjunction with SAP XI
 
Now I am a consultant and traine on Microsoft Dot Net (Also I got the MCSD.NET and MCAD.NET).

Comments and Discussions

 
Questionpermission to use derivative works PinmemberMember 1100140018-Aug-14 5:50 
GeneralWould like to experiment your demo on Vista. PinmemberSuperMiQi21-Sep-10 7:47 
GeneralCOM based application Pinmemberkalidoss_mca26-May-10 21:48 
GeneralI want to send message to client Pinmemberkennyuqz29-Dec-09 7:11 
GeneralRe: I want to send message to client Pinmemberesefer16-Jun-10 22:48 
GeneralQuery in remoting concept PinmemberJes_Latha13-Oct-08 3:33 
GeneralWell Done - Great example PinmemberMember 29761938-Oct-08 22:46 
GeneralSend event from server (easyInvoke) to client Pinmemberleasy20-May-08 21:32 
Generalabout Singlton Type usage PinmemberMember 432084418-May-08 12:43 
GeneralError running example Pinmemberolly.cox24-Aug-07 0:14 
GeneralRe: Error running example PinmemberMember 53486729-Feb-08 12:11 
QuestionDCOM Program Written C++ PinmemberKhosinski27-Jun-07 5:31 
AnswerRe: DCOM Program Written C++ PinmemberRicardo Fig27-Jun-07 7:33 
Questionis it possible to use remoting in PPC WM5? Pinmemberchushumor11-Jun-07 2:58 
QuestionPurpose of Remoting? PinmemberRadha Krishnan M22-May-07 4:29 
Questionwhat channel is this using? Pinmemberneodeaths2-May-07 17:45 
QuestionProblems with the event's handlers Pinmemberlennonblanco10-Apr-07 13:44 
AnswerRe: Problems with the event's handlers Pinmemberlennonblanco12-Apr-07 12:24 
QuestionServer Reply PinmemberMember #384992022-Feb-07 0:24 
AnswerRe: Server Reply Pinmembervanvaerenbergh16-Mar-07 11:50 
GeneralChange to use http and web page listener Pinmembernesr20-Sep-06 6:32 
GeneralProblem running sample PinmemberIkeRoss17-Aug-06 6:01 
GeneralRe: Problem running sample PinmemberRicardo Fig17-Aug-06 6:30 
GeneralRe: Problem running sample PinmemberIkeRoss17-Aug-06 6:49 
GeneralRe: Problem running sample PinmemberRicardo Fig17-Aug-06 6:51 

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 | Terms of Use | Mobile
Web01 | 2.8.141220.1 | Last Updated 1 May 2005
Article Copyright 2005 by Ricardo Fig
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid