Reputation: 635
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
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:
Upvotes: 1