Click here to Skip to main content
15,867,488 members
Articles / Programming Languages / C#
Article

Remote Objects Part 1

Rate me:
Please Sign up or sign in to vote.
4.44/5 (9 votes)
19 Mar 20023 min read 99.2K   1.4K   50   8
This demo shows how to create remote objects with callback functions and use them in the window host.

 

  

Introduction

.NET Remote objects can be hosted in the .NET Windows EXE server, the Internet Information Server (IIS) and the .NET component services. Using object references to communicate between server objects and clients is the heart of remote. The remote objects are reusable and lets you design a business logic object model according to the needs of the application.

The real strength of the remote system is its ability to transport messages between remote objects in different application domains or processes using different transportation protocols, serialization formats, object lifetime schemes.

The server object that has the ability to handle the callback is very important for some type of service. For example, when user logon the Auction server to bid an item, the user need to know the current price of the item. This requires the Auction Server to have the callback function to send the price information to all the users they are bid on the item.

In this article we only discuss how to use event handler to register the client's callback function (My next article “Remote Object Part 2” will discuss the client sink its instance to the server). The Server Object declare three events that can be used by the client to register the event handler in their host or register their callback function with which client can be called when the event raise. The clients use server's event handler to register their callback function is very easy.

C#
 SrvObj.SrvMessaging += new ServerEventHandler(CltObj.ServerMsgHandler);

This code add event handler CltObj.ServerMsgHandler to the event SrvMessaging on SrvObj.

The delegate is derived from System.MupticasetDelegate, which has a linked list that can hold any number of the event handler function. So, one event can have multiple event handlers. This means one event on the server object can handle all the callback function of the clients that is registered on that event.

The disadvantage of using event handler to register callback is not flexible for clients and the Server side can’t control over the clients to register callback function. If server wants to add more event handlers for different purpose, the client program has to change its code to use these new event handlers.

Server Object:

C#
namespace WremoteServer                                                              
{
      // Define the event                                                            
      public delegate void ServerEventHandler (object sender, RemoteEventArgs e);

      public class RemoteServer : MarshalByRefObject
      {                                                                              
            public static event ServerEventHandler InvokeHostForm;
            public event ServerEventHandler SrvMessaging;
            public event ServerEventHandler SrvMessaging2;
                                                                                     
            public void RemoteServerMethod(string str, out string strOut)
            {                                                                        
                  string tmp=string.Format("RemoteServerMethod is called: {0}",str);
                  RemoteEventArgs e = new RemoteEventArgs(tmp);

                  // Fire server form event
                  if(InvokeHostForm != null)
                        InvokeHostForm(this, e);
                                                                                     
                  strOut = str + " Returned from Server!";
            }                                                                        
            public void SendMsgToClient(string str)                                  
            {                                                                        
                  RemoteEventArgs e = new RemoteEventArgs(str);                      
                  // Fire Client Event                                               
                  if (SrvMessaging != null)                                          
                        SrvMessaging(this, e);                                       
            }                                                                        
            public void SendMsgToClient2(string str)                                 
            {                                                                        
                  RemoteEventArgs e = new RemoteEventArgs(str);                      
                  // Fire Client Event                                               
                  if (SrvMessaging2 != null)                                         
                        SrvMessaging2(this, e);                                      
            }                                                                        
      }                                                                              
}

Client Object:

C#
namespace WremoteClient                                                              
{                                                                                    
      public delegate void CFormEventHandler(object sender, RemoteEventArgs e);      
      public class RemotingClient : MarshalByRefObject                               
      {                                                                              
            public event CFormEventHandler InvokeFormMethod;                         
            [OneWay]                                                                 
            public void ServerMsgHandler(object sender, RemoteEventArgs e)           
            {                                                                        
                  if(InvokeFormMethod != null)                                       
                        InvokeFormMethod(this, e);                                   
            }                                                                        
      }                                                                              
} 

Client host:

C#
// connect to server object without register callback                                
private void ConnSrv_Click(object sender, System.EventArgs e)                        
{                                                                                    
      try                                                                            
      {                                                                              
            if (registedChan != null)                                                
            {                                                                        
                  ChannelServices.UnregisterChannel(registedChan);                   
                  registedChan = null;                                               
                        unRegistAll();                                               
            }                                                                        
            HttpChannel chan = new HttpChannel(Int32.Parse(port.Text));              
            ChannelServices.RegisterChannel(chan);                                   
            registedChan = chan;                                                     
            SrvObj = (RemoteServer)Activator.GetObject(                              
                  typeof(WRemoteServer.RemoteServer),                                
                  "http://localhost:8085/RemoteObj");                                
            if (SrvObj == null)                                                      
                  lb.Items.Add("Can't connect to server");                           
            else                                                                     
            {                                                                        
                  string strServer;                                                  
                  SrvObj.RemoteServerMethod(tb.Text + " from the client",            
                                            out strServer);    
                  lb.Items.Add(strServer);                                           
            }                                                                        
      }                                                                              
      catch(Exception e2)                                                            
      {                                                                              
            lb.Items.Add(e2.Message);                                                
      }                                                                              
}                                                                                    


// register callback on the msg1                                                     
private void ForMsg1_Click(object sender, System.EventArgs e)                        
{                                                                                    
      if(callbackFlg == false && registedChan != null)                               
      {                                                                              
            RemotingConfiguration.RegisterWellKnownServiceType(                      
                  Type.GetType("WRemoteClient.RemotingClient, RemotingClient"),      
                  "ClientObj",                                                       
                  WellKnownObjectMode.Singleton);                                    
                                                                                     
            string url=String.Format("http://localhost:{0}/ClientObj", port.Text);   
            CltObj = (RemotingClient)Activator.GetObject(                            
                  typeof(WRemoteClient.RemotingClient),                              
                  url);                                                              
                                                                                     
            SrvObj.SrvMessaging += new ServerEventHandler(CltObj.ServerMsgHandler);  
            CltObj.InvokeFormMethod += new CFormEventHandler(OnMsgHandler);          
            string strServer;                                                        
            SrvObj.RemoteServerMethod("Callback is registed!", out strServer);       
            callbackFlg = true;                                                      
      }                                                                              
}         

Steps to run the sample:

  1. Compile the Remote object by running makefile.bat at RemoteObj directory.
  2. Compile the WremoteClient and the WremoteServer. You may need to change the references to these DLL.
  3. Copy all the DLL files in RemoteObj directory to the WremoteClient\bin\Debug and WRemoteServer\bin\Debug directory.
  4. Run WRemoteServer.exe
  5. Run WRemoteClient.exe, then Click Connect Server, after this, you can send message to server and get the return message.
  6. Click register callback to select which message do you want to registered, after this, the client is waiting for the server message on the open channel.

Note:

When you want to start more than one client on the same machine, You should select different port number for the channel that is reserved for the callback.

This demo is updated with .Net framework 1.0 Version 1.0.3705. The Beta2 user may need to replace the control with Beta2 to make it work.

If you have any comments, I would love to hear about it. You can reach me at Jibin Pan.

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questiontrouble cross threading in .NET vs 2005 Pin
bibiboule2-Jan-07 22:03
bibiboule2-Jan-07 22:03 
GeneralClosing client causes error Pin
ty197510-Jan-05 16:55
ty197510-Jan-05 16:55 
GeneralError- 'Specified Cast Not Valid' while accessing remote COM objects Pin
Anonymous10-Oct-04 22:58
Anonymous10-Oct-04 22:58 
General.net 2003 Pin
dariush_hk18-Oct-03 4:11
dariush_hk18-Oct-03 4:11 
GeneralSecurity Problem in 1.1 Pin
pastoda19-Aug-03 5:57
pastoda19-Aug-03 5:57 
GeneralRe: Security Problem in 1.1 Pin
sympthom 928-Dec-03 3:43
sympthom 928-Dec-03 3:43 
GeneralRe: Security Problem in 1.1 Pin
Anonymous19-Dec-04 7:41
Anonymous19-Dec-04 7:41 
Generalproblem Pin
Rumen Yankov15-Nov-02 23:08
Rumen Yankov15-Nov-02 23:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.