Среда Remoting имеет штатную возможность описания своей конфигурации в XML-файле. К конфигурации среды Remoting относятся:
Разработчик может задать конфигурацию среды Remoting непосредственно в программе, но данный метод рассматриваться не будет. Применение файлов конфигураций позволяет отделить используемый в программе удаленный объект от места его физического размещения, и допускает настройку одного и того же распределенного приложения на использование различных каналов передачи данных без изменения исходного кода программы. Данная возможность должна всегда использоваться разработчиками, поэтому далее будет рассматриваться использование среды Remoting только с файлами конфигурации. После корректного конфигурирования среда Remoting обеспечивает прозрачное использование удаленных объектов (рис. 8.4).
Файл конфигурации на стороне, где находится маршализируемый по ссылке объект, используется приложением, являющимся сервером среды Remoting. В роли такого приложения может выступать либо IIS, либо пользовательская программа, обычно реализованная как сервис операционной системы. Для учебных целей можно воспользоваться следующим сервером .NET Remoting.
// server.cs using System; using System.Runtime.Remoting; using System.Configuration; public class Server { public static void Main(string[] args) { string config = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; Console.WriteLine(config); RemotingConfiguration.Configure(s); // Для .NET Framework 2.0 рекомендуется использовать // RemotingConfiguration.Configure(s, false); Console.WriteLine("Нажмите ENTER для завершения работы сервера."); Console.ReadLine(); } }
Как видно из приведенного примера, назначение такого сервера – настройка среды Remoting на основе содержимого стандартного конфигурационного файла программы.
Не претендуя на полное изложение всех возможностей конфигурационного файла среды Remoting, рассмотрим следующий пример конфигурации сервера.
<configuration> <system.runtime.remoting> <application> <service> <wellknown mode="SingleCall" type="RemoteTest.TestService, RemoteTestService" objectUri="endpoint"/> </service> <channels> <channel ref="tcp" port="2080" /> </channels> </application> </system.runtime.remoting> </configuration>
В разделе <application> <service> указываются публикуемые сервером объекты. Для каждого из них указывается модель вызова, имя класса (через запятую идет полное или краткое имя сборки, которая содержит класс), и уникальный URI, связываемый с данным классом. Объекты, активируемые сервером, описываются как
<wellknown mode="SingleCall" type=...
для режима единственного вызова или
<wellknown mode="Singletone" type=...
для режима одного экземпляра. Объекты, активируемые по запросу клиента, описываются иначе.
<activated type=...
Раздел <application><channels> сервера в простейшем случай содержит идентификатор канала и номер порта. Стандартные каналы имеют идентификаторы, соответствующие названиям их протоколов. В файле конфигурации могут использоваться модифицированные или вновь созданные каналы, как будут показано далее.
Файл конфигурации клиента обычно выглядит примерно следующим образом.
<configuration> <system.runtime.remoting> <application> <client> <wellknown mode="SingleCall" type="RemoteTest.TestService, RemoteTestService" objectUri="tcp://127.0.0.1:2080/endpoint" /> </client > </application> </system.runtime.remoting> </configuration>
Раздел <application><client> включает описание используемых удаленных объектов. Следует отметить, что один и тот же файл может содержать и разделы <service>, и <client>.
Программа при этом будет настроена как сервер и клиент Remoting одновременно.
Клиент, использующий удаленный объект, сначала должен настроить среду Remoting. После чего при создании объекта любого из перечисленных в файле конфигурации в разделе <client> классов будет создан посредник, связанный с соответствующим удаленным объектом.
using System; using System.Runtime.Remoting;
using RemotingTest;
public class Client { public static void Main(string[] args) { string config = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; Console.WriteLine(config); RemotingConfiguration.Configure(config);
// Для объекта единственого вызова в следующей строчке будут // созданы посредники, конструктор самого объекта не вызывается TestService service = new RemotingTest.TestService(); // При удаленном вызове на сервере будет сконструирован новый объект Console.WriteLine(service.Sum(2, 2)); } }
Ниже приведен код самого маршализируемого по ссылке объекта. Конструктор и деструктор объекта выводят сообщения в консоль, чтобы продемонстрировать моменты создания и удаления объекта на сервере.
// TestService.cs using System; namespace RemotingTest { public class TestService : MarshalByRefObject { public TestService() { Console.WriteLine("[ctor]"); }
~TestService() { Console.WriteLine("[dtor]"); }
public int Sum(int a, int b) { return a + b; } } }
Нижеследующий make файл позволяет собрать все приведенные выше файлы. Следует отметить, что в некоторых реализациях CLI для компиляции следует использовать ссылку на сборку System.Runtime.Remoting.dll. В .NET Framework 2.0 эта ссылка добавлена в стандартный файл параметров компилятора C# (csc.rsp).
makefile : Server.exe Client.exe
Server.exe : Server.cs csc Server.cs
Client.exe : Client.cs RemoteTestService.dll csc /r:RemoteTestService.dll Client.cs
RemoteTestService.dll: TestService.cs csc /out:RemoteTestService.dll /t:library TestService.cs