Функциональность.Net Remoting
Недавно я начал с удаленного взаимодействия.Net, и мне удалось приступить к работе с некоторыми простыми учебными пособиями, такими как создание библиотеки dll, которая работает как калькулятор, к которому клиент может обращаться и использовать ( https://www.youtube.com/watch?v=Ve4AQnZ-_H0).
То, что я ищу, чтобы понять, как я мог получить доступ к текущей информации, которая хранится на сервере. Например, если у меня есть эта простая часть, работающая на сервере:
int x = 0;
while (!Console.KeyAvailable)
{
x++;
System.Threading.Thread.Sleep(1000);
Console.WriteLine(x);
}
До сих пор я обнаружил, что созданная dll возвращает только статический результат, например, с помощью калькулятора. Я хотел бы быть в состоянии сказать, сколько х на сервере в любой момент времени, через клиента.
Я не знаю, достаточно ли я ясен, но постараюсь объяснить лучше, если это необходимо.
1 ответ
В следующей реализации Сервера демонстрируется, как можно поддерживать состояние между вызовами.
// 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;
}
}
Обратите внимание на переопределение InitializeLifetimeService
, Если вы не контролируете это, ваш экземпляр будет разрушен через 5 минут.
Чтобы использовать вышеприведенный класс, мы используем следующий код для запуска и работы слушателя, включая часть вашей логики. Не забудьте добавить ссылку на сборку 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);
}
}
Когда этот код выполняется, он должен прослушивать ваш локальный ящик на порту 1234 для соединений. При первом запуске мне пришлось отключить брандмауэр, разрешить этому порту проходить через локальный брандмауэр.
Клиентская реализация, которая использует Server
может выглядеть так Не забудьте добавить ссылку на сборку 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");
}
Если вы скомпилируете и запустите это, ваш результат может выглядеть так: