// "Жестко" заданная программная логика сервера HTTP.
HttpChannel с = new HttpChannel(32469);
ChannelServices.RegisterChannel(с);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(SimpleRemotingAsm.RemoteMessageObject), "RemoteMsgObj.soap", WellKnownObjectMode.Singleton);
Используя элементы ‹service›, ‹wellknown› и ‹channels›, эту программную логику можно заменить следующим файлом *.config.
‹configuration›
‹system.runtime.remoting›
‹application›
‹service›
‹wellknown mode="Singleton" type="SimpleRemotingAsm.RemoteMessageObject, SimpleRemotingAsm" objectUri="RemoteMsgObj.soap"/›
‹/service›
‹channels›
‹channelref="http"/›
‹/channels›
‹/application›
‹/system.runtime.remoting›
‹/configuration›
Обратите внимание на то, что значительная часть информации удаленного сервера указывается в контексте элемента ‹service› (не сервер! ). Его дочерний элемент ‹wellknown› использует три атрибута (mode, type и objectUri) для регистрации WKO-объекта в слое удаленного взаимодействия .NET. Элемент ‹channels› может содержать любое число элементов ‹channel›, которые позволяют определить вид канала (в данном случае это HTTP), открываемого на сервере. Для ТСР-каналов вместо http нужно просто использовать лексему tcp.
Поскольку в этом случае вся необходимая информация содержится в файле SimpleRemoteObjectServer.exe.config, метод Main() серверной стороны значительно упрощается. В нем остается выполнить только вызов RemotingConfiguration.Configure() и указать имя соответствующего файла конфигурации.
static void Main(string[] args) {
// Регистрация WKO-объекта с помощью файла *.config.
RemotingConfiguration.Configure("SimpleRemoteObjectServer.exe.config");
Console.WriteLine("Старт сервера! Для остановки нажмите ‹Enter›");
Console.ReadLine();
}
Создание файлов *.config клиента
Клиенты тоже могут использовать файлы * .config удаленного взаимодействия. В отличие от файлов конфигурации сервера, в файлах конфигурации клиента для идентификации имени WKO-объекта используется элемент ‹client›. Вдобавок к возможности динамического изменения параметров удаленного взаимодействия без перекомпиляции базового программного кода, файлы *.config клиента позволяют создать тип агента непосредственно с помощью ключевого слова C# new, не используя метод Activator.GetObject(). Предположим, например, что у нас есть файл *.config клиента со следующим содержимым.
‹configuration›
‹system.runtime.remoting›
‹application›
‹client displayName = "SimpleRemoteObjectClient"›
‹wellknown type=" SimpleRemotingAsm.RemoteMessageObject, SimpleRemotingAsm" url="http://localhost:32469/RemoteMsgObj.soap"/›
‹/client›
‹channels›
‹channel ref="http"/›
‹/channels›
‹/application›
‹/system.runtime.remoting›
‹/configuration›
Тогда можно изменить метод Main() клиента так.
statiс void Main(string[] args) {
RemotingConfiguration.Configure("SimpleRemoteObjectClient.exe.config");
// При использовании файла *.config клиент может создать тип
// непосредственно с помощью ключевого слова 'new'.
RemoteMessageObject simple = new RemoteMessageObject();
simple.DisplayMessage("Привет от клиента!");
Console.WriteLine("Сервер говорит: {0}", simple.ReturnMessage());
Console.WriteLine("Старт клиента! Для остановки нажмите ‹Enter›");
Console.ReadLine();
}
При выполнении этого варианта приложения вывод оказывается аналогичным исходному. Если клиент пожелает использовать TCP-канал, то для свойств url элемента ‹wellknown› и ref элемента ‹сhannel› следует вместо http указывать tcp.
Исходный код. Проекты SimpleRemoteObjectServerWithConfig и SimpleRemoteObjectClientWithConfig размещены в подкаталоге, соответствующем главе 18 (оба эти проекта используют созданный выше компоновочный блок SimpleRemotingAsm.dll).
Наши первые приложения удаленного взаимодействия позволяли доступ клиентов к одному WKO-типу. Напомним, что WKO-типы (по определению) являются MBR-типами, поэтому доступ клиента к ним осуществляется через агента-посредника. В противоположность этому, MBV-типы являются локальными копиями серверного объекта, обычно возвращаемыми открытыми членами некоторого MBR-типа. Вы уже знаете, как настроить MBV-тип (следует обозначить соответствующий класс атрибутом [Serializable]), но MBV-тип в действии вы еще не видели (если не считать обмена строковыми данными между двумя сторонами). Для иллюстрации взаимодействия MBR- и MBV-типов мы рассмотрим новый пример, в котором используются следующие три компоновочных блока.
• Общий компоновочный блок CarGeneralAsm.dll
• Компоновочный блок клиента CarProviderClient.exe
Читать дальше