Чтение онлайн

ЖАНРЫ

ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

Троелсен Эндрю

Шрифт:

 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).

Работа с MBV-объектами

Наши первые приложения удаленного взаимодействия позволяли доступ клиентов к одному WKO-типу. Напомним, что WKO-типы (по определению) являются MBR-типами, поэтому доступ клиента к ним осуществляется через агента-посредника. В противоположность этому, MBV-типы являются локальными копиями серверного объекта, обычно возвращаемыми открытыми членами некоторого MBR-типа. Вы уже знаете, как настроить MBV-тип (следует обозначить соответствующий класс атрибутом [Serializable]), но MBV-тип в действии вы еще не видели (если не считать обмена строковыми данными между двумя сторонами). Для иллюстрации взаимодействия MBR- и MBV-типов мы рассмотрим новый пример, в котором используются следующие три компоновочных блока.

• Общий компоновочный блок CarGeneralAsm.dll

• Компоновочный блок клиента CarProviderClient.exe

• Компоновочный блок сервера CarProviderServer.exe

Как вы можете догадаться, программный код приложений клиента и сервера более или менее подобен программному коду соответствующих приложений предыдущего примера, особенно в том, как эти приложения используют файлы *.config, Тем не менее, давайте разберем соответствующий процесс построения каждого из указанных компоновочных блоков по очереди.

Создание общего компоновочного блока

В ходе нашего обсуждения процесса сериализации объектов в главе 17 мы создали тип JamesBondCar (в дополнение к связанным классам Radio и Car). Библиотека программного кода CarGeneralAsm.dll будет использовать эти типы, поэтому сначала выберите Projects->Add Existing Item из меню и добавьте в свой новый проект библиотеки классов соответствующие файлы *.cs (автоматически созданный файл Class1.cs можете удалить), Поскольку каждый из добавленных типов уже обозначен атрибутом [Serializable], они готовы для маршалинга по значению в отношении удаленного клиента.

Теперь нам нужен MBR-тип, который обеспечит доступ к типу JamesBondCar. Чтобы сделать ситуацию немного более интересной, ваш MBR-объект (CarProvider) будет поддерживать обобщенный список List‹› типов JamesBondCar. Тип CarProvider определит два члена, которые позволят вызывающей стороне получить заданный тип JamesBondCar, а также полный перечень List‹› соответствующих типов. Вот весь программный код для нового типа класса.

namespace CarGeneralAsm {

 // Этот тип является MBR-объектом, обеспечивающим доступ

 // к соответствующим MBV-типам.

 public class CarProvider: MarshalByRefObject {

private List‹JamesBondCar› theJBCars = new List‹JamesBondCar›;

//
Добавление в список нескольких машин.

public CarProvider {

Console.WriteLine("Создание поставщика машин");

theJBCars.Add(new JamesBondCar("QMobile", 140, true, true"));

theJBCars.Add(new JamesBondCar("Flyer", 140, true, false));

theJBCars.Add(new JamesBondCar("Swimmer", 140, false, true));

theJBCars.Add(new JamesBondCar("BasicJBC", 140, false, false));

}

// Получение всех JamesBondCar.

public List‹JamesBondCar› GetAllAutos { return theJBCars; }

// Получение одного JamesBondCar,

public JamesBondCar GetJBCByIndex(int i) { return (JamesBondCar)theJBCars[i]; }

 }

}

Обратите внимание на то, что метод GetAllAutos возвращает внутренний тип List‹›. Очевидный вопрос: как данный член пространства имен System. Collections.Generic представляется вызывающей стороне? Если посмотреть описание этого типа в документации .NET Framework 2.0 SDK, вы обнаружите, что list‹› сопровождается атрибутом [Serializable].

[SerializableAttribute]

public class List‹T›: IList, ICollection, IEnumerable

Таким образом, для всего содержимого типа List‹› будет использован маршалинг по значению (если содержащиеся в нем типы также допускают сериализацию). Это очень удобная особенность удаленного взаимодействия .NET и членов библиотек базовых классов. Вдобавок к пользовательским MBV- и MBR-типам, которые вы можете создать сами, любой тип из библиотек базовых классов, сопровождающийся атрибутом [Serializable], также способен выступать в качестве MBV-типа в архитектуре удаленного взаимодействия .NET. Аналогично, любой тип, получающийся (непосредственно или косвенно) из MarshalByRefObject, может функционировать, как MBR-тип.

Замечание. Следует знать о том, что SoapFormatter не поддерживает сериализацию обобщенных типов. При создании методов, получающих или возвращающих обобщенные типы (напри-мер, List‹›), вы должны использовать BinaryFormatter и объект TcpChannel.

Создание компоновочного блока сервера

Компоновочный блок сервера (CarProviderServer.exe) в рамках метода Main содержит следующую программную логику.

using System;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Http;

using CarGeneralAsm;

namespace CarProviderServer {

 class CarServer {

static void Main(string[] args) {

RemotingConfiguration.Configure("CarProviderServer.exe.config");

Console.WriteLine("Старт сервера! Для остановки нажмите ‹Enter›");

Поделиться с друзьями: