Member Avatar for Member #854990

Hi all,

I have code which allows a client console to connect to a server console using .NET Remoting with a shared dll, and then perform some operations. The only problem I'm aving, is that I want the main bulk of the programming logic to be performed on the server itself (within the server class, not the library) - to access the database etc. Eventually the (multiple) Clients and Server application will be on seperate physical machines (for now they are on one). Below is the code I have so far. The server console says "press any key", and the client will say "Name: Test". I want this information to be available on the Server application!!!

The general idea of this set up is to pass the MyObj class between client and server (the client can request a MyObj with data, or it can send it as part of a method param). I then need this class to be available on the Server app where it will retrieve/store the classes' data into a database, and perform additional logic on the data, and then pass it back to the client.

//Server code
 public class Server
 {
  public static void Main(String[] args)
  {
   TcpServerChannel channel = new TcpServerChannel(9932);
   ChannelServices.RegisterChannel(channel);
   RemotingConfiguration.RegisterWellKnownServiceType(typeof(ObjLoader),
     "ObjLoader", WellKnownObjectMode.SingleCall);
   System.Console.WriteLine("press Any Key");
   System.Console.ReadLine();
  }
 }
//class Library Code
 public class ObjLoader : System.MarshalByRefObject
 {

  public ObjLoader ()
  {
   System.Console.WriteLine("Connected!");
  }

  public MyObj GetObj(int id)
  {
   MyObj myObj = new MyObj(10);
   //myObj.id = 10;
   myObj.name = "Test";
   return myObj;
  }
 }


[Serializable]
public class MyObj
{
  private int id;
  private String name;

 public MyObj(int _id)
  {
   this.id = _id;
   this.name = "default name";
  }
  public String name
  { get { return this.name; } }
}
//Client code
public class Client
 {

  public static void Main(string[] args)
  {

   try
   {
    ChannelServices.RegisterChannel(new TcpClientChannel());
    ObjLoader loader = (ObjLoader)Activator.GetObject(
     typeof(ObjLoader), "tcp://localhost:9932/ObjLoader");

    if (loader == null)
    { Console.WriteLine("Unable to connect"); }
    else
    {
     MyObj myObj = loader.GetObj(10);
     Console.WriteLine("Name:" + myObj.name);
    }
   }

  catch (Exception e)
   {
    Console.WriteLine("ERROR: {0}", e.Message);
   }
   
   Console.ReadLine();//Keep the window from closing before we can read the result.
}

So, really what I want is for the GetObj(int id) to call a method on the server to get data from a SQL database hosted on the same server. From my limited knowledge of .Net Remoting, the shared dll needs to be on both client and server ... so how is this to be done? Any suggestions?

If I need to make anything clearer, please let me know.

Many Thanks in advance!

Michael

Dani AI

Generated

Quick summary and practical fixes for the original Remoting approach (and why switching to WCF, as suggested, was a sensible move).

Your ObjLoader already runs on the server because it inherits MarshalByRefObject — calls to GetObj execute server-side. The key point people often miss: the object you return is a different thing. If MyObj is marked [Serializable] it gets copied to the client (by-value). If you want the object to remain server-owned and be operated remotely, MyObj itself must extend MarshalByRefObject (and the client will get a proxy). If you want simple data transfer, return a DTO (serializable) and keep all DB and business logic inside server methods.

A couple of concrete corrections based on the posted code:

  • The MyObj property/field uses the same identifier; that will either fail to compile or cause recursion. Use distinct names or auto-properties, e.g. private string _name; public string Name { get { return _name; } set { _name = value; } }.
  • Choose the remoting lifecycle deliberately: WellKnownObjectMode.SingleCall creates a fresh server instance per call (no in-memory state). Use Singleton if you need stateful behavior on the server.

Practical checklist to make the server do the heavy lifting

  • Put all DB access and business rules in server-side methods (inside ObjLoader or a repository it calls). Return plain data DTOs to clients.
  • If clients must call methods on returned objects and have those execute on the server, make those objects inherit MarshalByRefObject and ensure the shared assembly with the types is available to both sides.
  • Watch for version/assembly mismatches and firewall/port issues when calls silently fail.
  • For WCF: define service contracts and data contracts (DTOs), host the service (console/Windows service/IIS), and choose an appropriate InstanceContextMode (PerCall/Single). WCF avoids many Remoting pitfalls around marshaling semantics.

If maintaining long-term cross-platform support, consider more modern transport options (HTTP/gRPC/REST) when moving beyond classic .NET Framework.

Recommended Answers

All 3 Replies

Not sure how to answer your question, but as a bit of info (only in case you didn't know) MSDN states that applications shouldn't be developed using this technology anymore and instead should be using WCF. MSDN Website.

This topic is specific to a legacy technology that is retained for backward compatibility with existing applications and is not recommended for new development. Distributed applications should now be developed using the Windows Communication Foundation (WCF).

Just a FYI. :)

Member Avatar for Member #854990

Hi, thanks for your help. I'm now using WCF with great success! :)

For those out there who also would like to use WCF for similar purposes, the following are really useful tutorials:

http://www.codeproject.com/KB/WCF/LinqWcfService.aspx

Glad it was helpful :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.