Когда сообщение получено на серверной стороне канала, оно передается приемникам серверного контекста. Последний из этих приемников направляет сообщение в цепочку объектных приемников.
Объектный приемник
Объектный приемник ассоциируется с определенным объектом. Если объектный класс определяет атрибуты определенного контекста, то для объекта создаются приемники контекста.
Передача объектов в удаленные методы
Типы параметров для вызовов удаленных методов не ограничены только базовыми типами данных, но могут также быть классами, которые определяет программист. Для удаленных методов различают три типа классов:
□ Классы, маршализуемые по значению, обычно сериализуются через канал. Классы, которые должны быть маршализованы, либо реализуют интерфейс 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;