Question

what's the problem with the following code... I have this Complex class:

public class Complex : MarshalByRefObject
    {

        public double imaginary{get;set;}
        public double real{get;set;}            

        public void setReal(double re)
        {
            real = re;
        }

        public void setImaginary(double im)
        {
            imaginary = im;
        }

        public Complex(double im, double re)
        {
            imaginary = im;
            real = re;
        }    

        public void writeMembers()
        {
            Console.WriteLine(real.ToString() + imaginary.ToString());
        }
    }

Actually, there's a little more to it, but the code it's too big, and we don't use the rest of it in the context of this.

Then, I implemented a server which listens for connections:

HttpChannel channel = new HttpChannel(12345);                
            ChannelServices.RegisterChannel(channel, false);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(SharedLib.Complex), "ComplexURI", WellKnownObjectMode.SingleCall);

            Console.WriteLine("Server started. Press any key to close...");
            Console.ReadKey();

            foreach (IChannel ichannel in ChannelServices.RegisteredChannels)
            {
                (ichannel as HttpChannel).StopListening(null);
                ChannelServices.UnregisterChannel(ichannel);
            }

Then, we have the client:

try
            {
                HttpChannel channel = new HttpChannel();
                RemotingConfiguration.Configure("Client.exe.config", false);

                Complex c1 = (Complex)Activator.GetObject(typeof(Complex), "http://localhost:12345/ComplexURI");                    


                if (RemotingServices.IsTransparentProxy(c1))
                {
                    c1.real = 4;
                    c1.imaginary = 5;    

                    c1.writeMembers();                    

                    Console.ReadLine();
                }
                else
                {
                    Console.WriteLine("The proxy is not transparent");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }

Then, I run the server, which opens a console window, and I run the client. Instead of displaying 4 and 5 on the server window, I merely get 00, a sign that the members weren't changed. How do I do, so the members change? Thanks.

Was it helpful?

Solution

The problem is that you're using WellKnownObjectMode.SingleCall. As the documentation says:

  • SingleCall Every incoming message is serviced by a new object instance.
  • Singleton Every incoming message is serviced by the same object instance.

See also the documentation for RegisterWellKnownServiceType:

When the call arrives at the server, the .NET Framework extracts the URI from the message, examines the remoting tables to locate the reference for the object that matches the URI, and then instantiates the object if necessary, forwarding the method call to the object. If the object is registered as SingleCall, it is destroyed after the method call is completed. A new instance of the object is created for each method called.

In your case, the statement c.Real = 4 is a call to the Real property setter. It makes a call to the remote object, which creates a new object, sets the Real property to 4, and returns. Then when you set the imaginary property, it creates a new object, etc.

If you want this to work, you'll have to use WellKnownObjectMode.Singleton. But you might want to ask yourself if you really want such a "chatty" interface. Every time you set a property, it requires a call through the proxy to the server.

And, finally, you might consider abandoning Remoting altogether. It's old technology, and has a number of shortcomings. If this is new development, you should be using Windows Communications Foundation (WCF). The Remoting documentation says:

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top