- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания C# для профессионалов. Том II - Симон Робинсон
Шрифт:
Интервал:
Закладка:
Приемники сообщений
Метод Activator.GetObject() вызывает RemotingServicesConnect() для соединения с хорошо известным объектом. В методе Connect() происходит Unmarshal(), где создается не только прокси, но и уполномоченные приемники. Прокси использует цепочку уполномоченных приемников для передачи сообщения в канал. Все приемники являются перехватчиками, которые могут изменять сообщение и выполнять некоторые дополнительные действия, такие как создание блокировки, запись события, выполнение проверки безопасности и т.д.
Все приемники событий реализуют интерфейс IMessageSink. Такой интерфейс определяет одно свойство и два метода:
□ Свойство NextSink используется приемником для получения следующего приемника и передачи сообщения дальше.
□ Для синхронных сообщений вызывается метод SyncProcessMessage() предыдущим приемником или удаленной инфраструктурой. Он имеет параметр IMessage для отправки и возврата сообщения.
□ Для асинхронных сообщений вызывается метод AsyncProcessMessage() предыдущим приемником в цепочке или удаленной инфраструктурой. AsyncProcessMessage() имеет два параметра, куда могут передаваться сообщение и приемник сообщения, который получает ответ.
Рассмотрим три доступных для использования приемника сообщения.
Уполномоченный приемник
Можно получить цепочку уполномоченных приемников с помощью интерфейса IEnvoyInfo. Маршализованная объектная ссылка ObjRef имеет свойство EnvoyInfo, которое возвращает интерфейс IEnvoyInfo. Список уполномоченных приемников создается из серверного контекста, поэтому сервер может добавлять функциональность клиенту. Уполномоченные приемники собирают информацию об идентичности клиента и предают ее серверу.
Приемник серверного контекста
Когда сообщение получено на серверной стороне канала, оно передается приемникам серверного контекста. Последний из этих приемников направляет сообщение в цепочку объектных приемников.
Объектный приемник
Объектный приемник ассоциируется с определенным объектом. Если объектный класс определяет атрибуты определенного контекста, то для объекта создаются приемники контекста.
Передача объектов в удаленные методы
Типы параметров для вызовов удаленных методов не ограничены только базовыми типами данных, но могут также быть классами, которые определяет программист. Для удаленных методов различают три типа классов:
□ Классы, маршализуемые по значению, обычно сериализуются через канал. Классы, которые должны быть маршализованы, либо реализуют интерфейс ISerializable, либо помечаются с помощью атрибута [Serializable]. Объекты этих классов не имеют удаленной идентичности, так как весь объект маршализуется через канал, а объект, который сериализуется клиенту, является независимым от серверного объекта (или наоборот). Классы, маршализуемые по значению, называются также несвязанными классами, так как они не имеют данных, которые зависят от домена приложения.
□ Классы, маршализуемые по ссылке, имеют удаленную идентичность. Объекты не передаются по линиям связи, а вместо этого возвращается прокси. Класс, который маршализуется по ссылке, должен выводиться из MarshalByRefObject. Объекты MarshalByRefObject называют объектами, связанными с доменом приложения. Специализированной версией MarshalByRefObject является класс ContextBoundObject: абстрактный класс ContextBoundObject выводится из MarshalByRefObject. Если класс выводится из ContextBoundObject, требуется прокси даже в том же самом домене приложения, когда пересекаются границы контекстов.
□ Классы, которые не являются сериализуемыми и не выводятся из MarshalByRefObject, не могут использоваться в параметрах открытых методов удаленных объектов. Эти классы связаны с доменом приложения, где они созданы. Такие классы должны использоваться, если класс имеет члены данных, допустимые только в домене приложения, такие как дескриптор файла Win32.
Чтобы увидеть маршализацию в действии, изменим удаленный объект для пересылки двух объектов клиенту: пусть класс MySerialized посылает маршализацию по значению, а класс MyRemote маршализует по ссылке. В методах сообщение записывается на консоль, чтобы можно было проверять, сделан ли вызов на клиенте или на сервере. Кроме того, класс Hello изменяется, чтобы возвращать экземпляры MySerilized и MyRemote:
using System;
namespace Wrox.ProfessionalCSharp {
[Serilizable]
public сlass MySerilized {
public MySerilized(int val) {
a = val;
}
public void Foo() {
Console.WriteLine("MySerialized.Foo called");
}
public int A {
get {
Console.WriteLine("MySerialized A called");
return a;
}
set {
a = value;
}
}
protected int a;
}
public class MyRemote : System.MarshalByRefObject {
public MyRemote(int val) {
a = val;
}
public void Foo() {
Console.WriteLine("MyRemote.Foo called");
}
public int A {
get
Сonsole.WriteLine("MyRemote.A called");
return a;
}
set {
a = value;
}
}
protected int a;
}
/// <summary>
/// Краткое описание Class1
/// </summary>
public class Hello : System.MarshalByRefObject {
public Hello() {
Console.WriteLine("Constructor called");
}
~Hello() {
Console.WriteLine("Destructor called");
}
public string Greeting(string name) {
Console.WriteLine("Greeting called");
return "Hello, " + name;
}
public MySerialized GetMySerilized() {
return new MySerialized(4711);
}
public MyRemote GetMyRemote() {
return new MyRemote(4712);
}
}
}
Клиентское приложение также необходимо изменить, чтобы увидеть результаты при использовании маршализации объектов по значению и по ссылке. Мы вызываем методы GetMySerialized() и GetMyRemote(), чтобы получить новые объекты и проверить, не используется ли прозрачный прокси.
ChannelServices.RegisterChannel(new TcpChannel());
Hello obj =
(Hello)Activator.GetObject(typeof(Hello),
"tcp://localhost:8086/Hi");
if (obj == null) {
Console.WriteLine("could not locate server");
return;
}
MySerialized ser = obj.GetMySerialized();
if (!RemotingServices.IsTransparentProxy(ser)) {
Console.WriteLine("ser is not a transparent proxy");
}
ser.Foo();
MyRemote rem = obj.GetMyRemote();
if (RemotingServices.IsTransparentProxy(rem)) {
Console.WriteLine("rem is a transparent proxy");
}
rem.Foo();
В консольном окне клиента видно, что объект ser вызывается на клиенте. Этот объект не является прозрачным прокси, так как он сериализуется клиенту. В противоположность этому, объект rem на клиенте является прозрачным прокси. Методы, вызванные для этого объекта, передаются на сервер:
В серверном выводе можно видеть, что метод Foo() вызывается с удаленным объектом MyRemote:
Направляющие атрибуты
Удаленные объекты никогда не передаются по линиям связи в отличие от типов данных значений и сериализуемых классов. Иногда желательно послать данные только в одном направлении. Это особенно важно, когда данные передаются по сета. С помощью COM можно было объявить для аргументов направляющие атрибуты [in], [out] и [in, out], если данные должны посылаться на сервер, клиенту или в обоих направлениях.
В C# существуют аналогичные атрибуты как часть языка: параметры методов ref и out. Параметры методов ref и out могут использоваться для типов данных значений и для ссылочных типов, которые способны сериализоваться. С помощью параметра ref аргумент маршализуется в обоих направлениях, out идет от сервера клиенту, а в отсутствие параметра метода посылает данные серверу.
Управление временем жизни
Как клиент и сервер определяют, какая возникла проблема и что при этом другая сторона более недоступна?
Для клиента ответ может быть коротким. Как только клиент вызывает метод для удаленного объекта, мы получаем исключение типа System.Runtime.Remoting.RemotingException. Необходимо просто обработать это исключение и сделать, например, повторную попытку или записать в журнал, информировать пользователя и т.д.