Solved

Help on remoting

Posted on 2004-09-02
10
388 Views
Last Modified: 2012-06-22
Ola,

I found a simple remoting example that consists of a remoting object a server and a client.
The client connects to the server that hosts the remoting object.

Now my question is how do I access the MethodIwantToRunRemotely in the server from the remoting object?
in other words:
How can I access the MethodIwantToRunRemotely method from the client via the remoting object?

here is the code:

// Remoting object
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace CodeGuru.Remoting
{
      public class SampleObject : MarshalByRefObject
      {
            public SampleObject()
            {
            }
            public string HelloWorld()
            {
                  return "Hello World!";
            }
      }
}

// Remoting server
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace CodeGuru.Remoting
{
      public class SampleServer
      {
            public static int Main(string [] args)
            {
                  TcpChannel channel = new TcpChannel( 8080 );
                  ChannelServices.RegisterChannel( channel );
                  RemotingConfiguration.RegisterWellKnownServiceType(
                        typeof( SampleObject ),
                        "HelloWorld",
                        WellKnownObjectMode.SingleCall
                  );
                  Console.WriteLine("Press the enter key to exit...");
                  Console.ReadLine();
                  return 0;
            }
            public static void MethodIwantToRunRemotely( string iStr )
            {
                  // do actions
            }
      }
}

// Remoting client
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace CodeGuru.Remoting
{
      public class SampleClient
      {
            public static int Main(string [] args)
            {
                  TcpChannel chan = new TcpChannel();
                  ChannelServices.RegisterChannel(chan);
                  SampleObject obj = (SampleObject) Activator.GetObject(
                        typeof(CodeGuru.Remoting.SampleObject),
                        "tcp://localhost:8080/HelloWorld"
                  );
                  if( obj.Equals(null) )
                  {
                        System.Console.WriteLine("Error: unable to locate server");
                  }
                  else
                  {
                        Console.WriteLine(obj.HelloWorld());
                  }
                  return 0;
            }
      }
}
0
Comment
Question by:DaFou
  • 5
  • 4
10 Comments
 
LVL 10

Expert Comment

by:123654789987
ID: 11988902
The method MethodIwantToRunRemotely should be declared in SampleObject not in Server.cs

U have to add a delegate above SampleObject. Then declare a event in SampleObject


using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace CodeGuru.Remoting
{
public delegate void MethodIwantToRunRemotely(string s;
     public class SampleObject : MarshalByRefObject
     {
public event  MethodIwantToRunRemotely event;
          public SampleObject()
          {
          }
          public string HelloWorld()
          {
               return "Hello World!";
          }
     }
}

Then u have to handle that event in the client using a eventhandler

0
 
LVL 5

Expert Comment

by:jjacksn
ID: 11993892
you don't even need delegates.  

public class SampleObject : MarshalByRefObject
     {
          public SampleObject()
          {
          }
          public string HelloWorld()
          {
               return "Hello World!";
          }
          public void yourMethod()
         {
               //do something
         }
     }

public class SampleClient
     {
          public static int Main(string [] args)
          {
               TcpChannel chan = new TcpChannel();
               ChannelServices.RegisterChannel(chan);
               SampleObject obj = (SampleObject) Activator.GetObject(
                    typeof(CodeGuru.Remoting.SampleObject),
                    "tcp://localhost:8080/HelloWorld"
               );
               if( obj.Equals(null) )
               {
                    System.Console.WriteLine("Error: unable to locate server");
               }
               else
               {
                    obj.yourMethod() //Server will execute this code
               }
               return 0;
          }

0
 
LVL 2

Author Comment

by:DaFou
ID: 11997583
123654789987, I have no idea what you mean. Please expand on the example

jjacksn, will yourMethod() that is a method in the remoting object be able to access vartiables inside of the server object?
I dont think so and thus your suggestion is not applicable.
0
 
LVL 5

Expert Comment

by:jjacksn
ID: 11998827
DaFou, yes, that class can access anything on the server.  That class goes inside of a dll that is shared by the client AND server.  Anything you want to refer to, of course must be made to compile on the client side as well.  

The architecture I like to use for this goes as follows:

Inside the remoting class you have a class variable that is an an interface that implements everything you need.  this interface is in the shared dll, but the implementations of this interface are in other dlls that reside only on the server side.  You set the reference to the implementaiton of the interface in some server intializing code.  all remote methods pass the call through to this interface.  Thus, if you were to just create an object client side (without first setting up remoting) there would be a null pointer error because the internal interface implementation has not been set.  

This allows you to change the back end without changing the shared dll, as well keeping the information that is shared between the client and server to a minimum.  

I find this architecture clean, and you can easily change you code between CAO, singletons, and SAO.  To keep state in the remote object itself, you need to use CAOs.  
0
 
LVL 2

Author Comment

by:DaFou
ID: 11999275
Thank you jjacksn for your explenation.
I am afraid that I dont have enoug experiance with interfaces to set this up in the code snipets i posted.

Could you do the interface for void YourMethod() ? ( so creating the interface in the remoting object and having the server object listen to that interface )

That would answer my question
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 5

Expert Comment

by:jjacksn
ID: 11999742
Interface are trivial, you just create a new class, and change the class keyword to interface.  write the signature for the methods you want, and then you can imlement the interface by using a colon after the class declaration.  

THIS IS IN THE SHARED DLL

public class SampleObject : MarshalByRefObject
     {
          public static YourInterface YourImplementation;  

          public SampleObject()
          {
          }
          public string HelloWorld()
          {
               return "Hello World!";
          }
          public void yourMethod()
         {
               YourImplementation();  
         }
     }

public YourInterface
{
          void YourMethod();
}

-------------------------------
THIS IS SERVER ONLY

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace CodeGuru.Remoting
{
     public class SampleServer
     {
          public static int Main(string [] args)
          {
               TcpChannel channel = new TcpChannel( 8080 );
               ChannelServices.RegisterChannel( channel );
               RemotingConfiguration.RegisterWellKnownServiceType(
                    typeof( SampleObject ),
                    "HelloWorld",
                    WellKnownObjectMode.SingleCall
               );
              // set the static instance
              SampleObject.YourImplmentation = new YourObject();

               Console.WriteLine("Press the enter key to exit...");
               Console.ReadLine();
               return 0;
          }
          public static void MethodIwantToRunRemotely( string iStr )
          {
               // do actions
          }
     }
}

//this means that you are implementing the interface YourInterface
public YourObject : YourInterface
{
     public void YourMethod()
     {
         //do something here
     }

}


--------------------------------
THIS IS CLIENT ONLY

public class SampleClient
     {
          public static int Main(string [] args)
          {
               TcpChannel chan = new TcpChannel();
               ChannelServices.RegisterChannel(chan);
               SampleObject obj = (SampleObject) Activator.GetObject(
                    typeof(CodeGuru.Remoting.SampleObject),
                    "tcp://localhost:8080/HelloWorld"
               );
               if( obj.Equals(null) )
               {
                    System.Console.WriteLine("Error: unable to locate server");
               }
               else
               {
                    obj.yourMethod() //Server will execute this code
               }
               return 0;
          }
0
 
LVL 2

Author Comment

by:DaFou
ID: 12000147
error messages i get when compiling the remoting object:
Expected class, delegate, enum, interface, or struct ( So i am guessing that 'public YourInterface' should be 'public interface YourInterface' )
The type or namespace name 'MarshalByRefObject' could not be found (are you missing a using directive or an assembly reference?)
Even after adding a reference to the remoting namespace

0
 
LVL 5

Expert Comment

by:jjacksn
ID: 12001663
DaFou,

MarshalByRefObject is in the System namespace. You shouldn't need a reference to anything extra.  It must be spelled wrong.  

Yes, public YourInterface should be

public interface YourInterface
0
 
LVL 2

Author Comment

by:DaFou
ID: 12003496
Still in the remoting object:

'SampleObject.YourImplementation' denotes a 'field' where a 'method' was expected

public void yourMethod()
{
      YourImplementation();  ( this is the line that generates the error )
}

are you sure this works at your end? I am kinda expecting for the server not to work aswell as

public YourObject : YourInterface ( does this not mean inherit instead of implement interface? )
{
     public void YourMethod()
     {
         //do something here
     }
}


I am so sorry that I cannot solve these problem all by myself yet, but I am learning c# on basis of an application in where I need remoting.
next to a 40 hr job it is hard to figure out what is going wrong on my own :-(

Please help out a bit more, I hope we are getting close
0
 
LVL 5

Accepted Solution

by:
jjacksn earned 500 total points
ID: 12007197
sorry, that should be

public void yourMethod()
{
     YourImplementation.YourMethod();  
}

YourObject is not to be declared on the client side, only the server side.  

SampleObject and YourInterface are declared in the dll that is shared.  
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now