?
Solved

Help on remoting

Posted on 2004-09-02
10
Medium Priority
?
411 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
Integration Management Part 2
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses
Course of the Month12 days, 19 hours left to enroll

578 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