?
Solved

Help on remoting

Posted on 2004-09-02
10
Medium Priority
?
401 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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 2000 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

Want to be a Web Developer? Get Certified Today!

Enroll in the Certified Web Development Professional course package to learn HTML, Javascript, and PHP. Build a solid foundation to work toward your dream job!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article introduced a TextBox that supports transparent background.   Introduction TextBox is the most widely used control component in GUI design. Most GUI controls do not support transparent background and more or less do not have the…
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…

752 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