Solved

Help on remoting

Posted on 2004-09-02
10
397 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
Industry Leaders: 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 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

Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

Question has a verified solution.

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

Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…

728 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