Benji
Benji

Reputation: 635

.Net Remoting functionality

I've recently started with .Net remoting and I have managed to get working with some simple tutorials such as building a library dll that works as a calculator which the client can access and use(https://www.youtube.com/watch?v=Ve4AQnZ-_H0).

What I'm looking for to understand is how I could access current information that is held on the server. For example if I have this simple part running on the server:

int x = 0;

while (!Console.KeyAvailable)
{
x++;
System.Threading.Thread.Sleep(1000);
Console.WriteLine(x);
}

What I found so far is that the dll built is only returning a static result, such as with the calculator. I'd want to be able to tell how much x is on the server at any given time, through the client.

I don't know if I'm being clear enough but I'll try to explain better if it's needed.

Upvotes: 1

Views: 387

Answers (1)

rene
rene

Reputation: 42494

In the following Server implementation demonstrates how you can keep state between calls.

// this gets instantiated by clients over remoting
public class Server:MarshalByRefObject
{
    // server wide state
    public static int Value;

    // state only for this instance (that can be shared with several clients
    // depending on its activation model)
    private StringBuilder buildup;

    // an instance
    public Server()
    {
        buildup = new StringBuilder();
        Console.WriteLine("server started");
    }

    // do something useful
    public int DoWork(char ch)
    {
        Console.WriteLine("server received {0}", ch);
        buildup.Append(ch);
        return Value;
    }

    // return all typed chars
    public string GetMessage()
    {
        Console.WriteLine("server GetMessage called") ;
        return buildup.ToString();
    }

    // how long should this instance live
    public override object InitializeLifetimeService()
    {
        // run forever
        return null;
    }
}

Notice the override InitializeLifetimeService. If you don't control this, your instance will get torn down after 5 minutes.

To use the above class we use the following code to get a listener up and running, including some of your logic. Don't forget to add an reference to the assembly System.Runtime.Remoting.

static void Main(string[] args)
{
    // which port 
    var chn = new HttpChannel(1234);
    ChannelServices.RegisterChannel(chn, false);

    // Create only ONE Server instance
    RemotingConfiguration.RegisterWellKnownServiceType(
        typeof(Server), "server", WellKnownObjectMode.Singleton);

    Server.Value = 0;
    while (!Console.KeyAvailable)
    {
        Server.Value++;
        System.Threading.Thread.Sleep(1000);
        Console.WriteLine(Server.Value);
    }
}

When this code runs, it should listen on your local box on port 1234 for connections. On first run I had to disable the firewall, allow that port to pass the local firewall.

A client implementation that uses the Server might look like this. Don't forget to add an reference to the assembly System.Runtime.Remoting.

static void Main(string[] args)
{
    var chn = new HttpChannel();
    ChannelServices.RegisterChannel(chn, false);

    RemotingConfiguration.RegisterWellKnownClientType(
        typeof(Server),
        "http://localhost:1234/server");

    Console.WriteLine("Creating server...");
    var s = new Server();

    Console.WriteLine("type chars, press p to print, press x to stop");
    var ch = Console.ReadKey();
    while(ch.KeyChar != 'x')
    {

        switch(ch.KeyChar )
        {
            case 'p':
                Console.WriteLine("msg: {0}", s.GetMessage());
                break;
            default:
                Console.WriteLine("Got value {0} ", s.DoWork(ch.KeyChar));
                break;
        }

            ch = Console.ReadKey();
    }
    Console.WriteLine("stopped");
}

If you compile and run this your result can look like this:

demo of client and server with remoting

Upvotes: 1

Related Questions