Биография Автореферат Библиотека Ссылки Отчет о поиске Идивидуальное задание

ПОСТРОЕНИЯ КЛИЕНТ-СЕРВЕРНОГО ПРИЛОЖЕНИЯ НА ОСНОВЕ .NET REMOTING.

Воротынцев Н.В.
ДонНТУ, каф. ВТИ


Статья подготовлена для сборника трудов магистров ДонНТУ.

Abstract

Vorotyntsev N.V. Building Client-Server application on basis of .NET Remoting
This article presents the overview of .NET Framework, .NET Remoting and how to build client-server applications using them.



Основы платформы .NET


   .NET – это новая модель для создания приложений (пока только под Windows). С точки зрения программиста .NET вполне можно рассматривать просто как новую среду выполнения и новую библиотеку базовых классов [3]. Среда выполнения обеспечивается с помощью Common Language Runtime (CLR, стандартная среда выполнения для языков). При компиляции кода для .NET компилятор генерирует код на общем промежуточном языке (common intermediate language, CIL), а не традиционный код, состоящий из процессорных команд. При исполнении CLR транслирует CIL в команды процессора. Поскольку трансляция выполняется в период выполнения, генерируются команды конкретного процессора. Это значит, что приложение .NET можно развертывать на любой машине, где работает CLR и FCL (Framework Class Library – базовая библиотека классов). .NET позволяет интегрироваться разным языкам, т.е. одному языку использовать типы созданные на других языках. Например, CLR позволяет создать класс на С++, производный от класса, реализованного на Visual Basic. CLR делает это возможным, так как она определяет и предоставляет общую систему типов (Common Type System, CTS), которую должны использовать все языки ориентированные на CLR.. Общеязыковая спецификация (Common Language Specification, CLS) определяет правила, которым должны следовать разработчики компиляторов, чтобы их языки интегрировались с другими.
   Специально для платформы .NET был разработан новый язык программирования C#, синтаксис которого очень похож на синтаксис Java. Основными особенностями C# являются: отсутствие указателей, автоматическое управление памятью, встроенные синтаксический конструкции для работы с перечислениями, структурами и свойствами классов, возможность перегрузки операторов, поддержка использования программных интерфейсов, возможность присваивания типам атрибутов.
   Когда с помощью компилятора для платформы .NET создается модуль DLL или EXE, в нем содержится сборка на языке IL. Помимо инструкций IL, модули .NET содержат также метаданные, которые подробно описывают все типы (классы), использованные в модуле, также полностью описываются все методы, свойства и события этого типа. Метаданные описывают не только типы, используемые в сборке, но и саму сборку. Эта часть метаданных называется манифестом. В манифесте содержится информация о текущей версии сборки, об использованных ограничениях по безопасности, о поддерживаемом естественном языке, а также список всех внешних сборок, которые потребуются для нормального выполнения. Таким образом, сборка является самоописываемой. Благодаря манифесту устраняется проблема с версиями и значительно упрощается развертывания приложения в системе.
   .NET Remoting – это объектно-ориентированная архитектура для поддержки распределенных приложений в Microsoft .NET [2]. Эта архитектура значительно упрощает, или, лучше того, организует, методы создания и расширения распределенных приложений [2] по сравнению с DCOM. .NET Remoting поддерживает множество стандартных сценариев, требуя лишь незначительных объемов работы или настройки. Это позволяет легко получить работоспособное распределенное приложение. Приложение может строиться из подключаемых модулей, поддерживающих определенный интерфейс подключения, например, можно подключить нужный тип канала (например, HTTP или TCP) и тип форматировщика (бинарный или SOAP). Таким образом можно выбирать из стандартных, но мощных конфигураций, просто подключая другой модуль. В настоящее время поддерживается несколько вариантов настройки распределенных приложений. Первый вариант – с помощью конфигурационных файлов. Настройка удаленного взаимодействия легко выполняется посредством файлов в формате XML. Эти файлы позволяют также выполнять установку приложения на компьютер путем простого копирования дерева каталогов и кроме того, они значительно облегчают сопровождение приложения. Второй вариант настройки это программный. Если изменение настройки распределенного приложения нежелательно, то можно полностью управлять им непосредственно из кода программы.
   Модель защиты для систем .NET Remoting существенно изменилась по сравнению со сложной и требующей больших объемов настройки модели DCOM. На данный момент предлагается помещать удаленный сервер внутрь IIS (Internet Information Services – информационные сервисы Интернет), что позволяет использовать его средства защиты, не внося изменения в код клиента или сервера. IIS предоставляет поддержку различных механизмов аутентификации, в том числе Windows-интегрированную (NTML), базовую, Passport и на основе сертификатов. Предоставляется также защита секретных данных, передаваемых между удаленными компьютерами, на основе SSL (Secure Sockets Layer). В настоящее время в .NET Remoting нет готового механизма защиты для распределенных приложений, не использующих IIS, однако архитектура подключаемых модулей позволяет написать собственный модуль защиты.


Архитектура .NET Remoting


   В .NET при исполнении приложения CLR выполняет контроль типов в коде и проверяет, не обращается ли код к недопустимым адресам, поэтому несколько приложений могут исполняться внутри одного процесса с сохранением тех же преимуществ изоляции приложений, что и в модели «одно приложение – один процесс». CLR определяет для приложений логическое подразделение: домен приложения. Код и объекты исполняющиеся в одном домене приложения, не имеют непосредственного доступа к коду и объектам, исполняющимся в другом домене приложения. Это обеспечивает защиту, так как сбой в одном домене не влияет на другие домены в том же процессе. Разделение между доменами приложения формирует границу .NET Remoting.
   .NET Remoting позволяет объктам, исполняющимся внутри разных доменов приложений, взаимодействовать друг с другом через границы .NET Remoting. С точки зрения инфраструктуры .NET Remoting объекты делятся на две категории: дистанцируемые и недистанцируемые. Экземпляры недистанцируемых типов не могут пересекать границы .NET Remoting ни при каких условиях. Разные категории дистанцируемых типов либо могут проникать через границы .NET Remoting, либо доступны через эти границы. .NET Remoting определяет такие категории дистанцируемых типов как передаваемые по значению и передаваемые по ссылке.
   Экземпляры типов, передаваемых по значению, пересекают границы .NET Remoting с помощью процесса, известного под названием сериализация, при которой текущее состояние объекта представляется в виде последовательности бит. После того как объект сериализован, он пересылается через границы .NET Remoting в другой домен приложения. в .NET Remoting тип считается если он объявлен с атрибутом Serializable.
   При передаче по ссылке все вызовы объекта, созданного в некотором домене приложения, обращаются именно к экземляру в данном домене, а не к его копии в другом домене. Чтобы сделать объект передаваемым по ссылке, достаточно его наследовать от System.MarshalByRefObject. Прежде чем работать с экземпляром дистанцируемого типа, его следует создать и инициализировать путем активизации. В .NET Remoting типы, передаваемые по ссылке, поддерживают два вида активизации: серверную и клиентскую. Типы, передаваемые по значению, не требуют особого механизма активизации, так как они копируются в процессе сериализации и активизируются в процессе десериализации. Режим активизации определяется не самим типом, а настройкой инфрастуктуры. Типы активизируемые сервером называются общеизвестными, так как серверный процесс, в котором находятся дистанцируемые типы, публикует их по определенным общеизвестным конечным точкам или адресам и активизирует экземпляры типа только при необходимости. .NET Remoting поддерживает два режима серверной активизации Singleton и SingleCall.
   В режиме Singleton в отдельный момент времени может быть активен только один экземпляр типа, который активизируется при первом обращении к нему клиента в отсутствии другого экземпляра. Экземпляр такого типа способен сохранять состояние в промежутке между вызовами. В режиме SingleCall обеспечивается модель программирования без сохранения состояния. Для типа, сконфигурированного как SingleCall, инфраструктура будет активизировать новый экземпляр при каждом вызове клиентом метода этого типа. После того как вызов метода обработан, экземпляр типа становиться доступным сборщику мусора.
   Когда необходимо, чтобы клиент работал с отдельным экземпляром удаленного объекта, используется клиентская активизация. Экземпляры таких типов могут оставаться активными в промежутках между вызовами методов и сохранять состояние.
   Для управления временем жизни удаленных объектов .NET Remoting использует вариант распределенной сборки мусора на основе лицензий. Лицензия – это объект, инкапсулирующий значения TimeSpan, которое содержит время жизни объекта. В каждом домене приложений имеется диспетчер лицензий, управляющий лицензиями экземпляров дистанцируемых объектов этого домена. При активизации удаленного объекта его лицензия передается диспетчеру лицензий, который периодически просматривает список лицензий, сравнивая время окончания действия лицензий с текущим временем. Каждая лицензия, срок действия которой истек, уведомляется об этом диспетчером лицензий, после чего она пытается себя продлить, опрашивая своих спонсоров. Если у лицензии нет спонсоров или никто ее не продлил, то она отменяет себя. Если лицензия объекта истекла, то она удаляется вместе с объектом, которому принадлежит. Спонсорами являются клиенты, которые подписываются на необходимый им удаленный объект.
   Для того чтобы передать объект по ссылке .NET Remoting выполняет создает экземпляр типа System.Runtime.Remoting.ObjRef и передает его по значению в целевой домен, где на основе этого типа создается объект-прокси (заместитель), посредством которого клиент может обращаться к удаленному объекту. ObjRef содержит метаданные передаваемого по ссылке объекта. При активизации экземпляра объекта, передаваемого по ссылке .NET Remoting назначает ему URI (Uniform Resource Identifier – унифицированный идентификатор ресурса), используемый клиентом при всех последующих обращения по ссылке на данный объект. Для непосредственной пересылки объектов через границы .NET Remoting используются каналы.
   Клиент, для взаимодействия с удаленным объектом, использует два вида прокси: прозрачный (TransparentProxy) и реальный (RealProxy). Клиент имеет непосредственный доступ к прозрачному прокси, который создается по информации из ObjRef с интерфейсом идентичным интерфейсу удаленного объекта. При вызове клиентом метода прозрачного прокси последний преобразует вызов в объект-сообщение и передает его реальному прокси, который отправляет его инфраструктуре .NET Remoting для доставки удаленному объекту.
   .NET Remoting пересылает сериализованные объекты-сообщения через границы посредством каналов, которые предоставляют транспортный механизм, обладающий большими возможностями по расширению и потенциальной возможностью поддержки самых разнообразных протоколов и сетевых форматов данных. Есть два стандартных типа канала: TCP и HTTP. Перед тем как сообщение будет передано в канал проходит через цепочку канальных приемников. Первым приемником является форматирующий приемник, отвечающий за сериализацию объекта-сообщения в поток байт определенного сетевого формата данных. Затем форматирующий приемник передает поток для дальнейшей обработки следующему приемнику в цепочке. Последний приемник в цепочке отвечает за пересылку потока байт по сети с использование определенного транспортного протокола. .NET Remoting предоставляет два типа форматирующих приемников: бинарный (BinaryFormatter) и SOAP-формата (SoapFormatter).


Пример построения клиент-серверного приложения на основе .NET Remoting


   В качестве примера на сервере будет выполняться аутентификация клиента с помощью имени клиента и его пароля. Для простоты имя и пароль будут передаваться в текстовом формате. В данном примере создается сервер объектов, который сам не предоставляет ни каких служб, а только отвечает за создание объекта, реализующего службу аутентификации. Ниже приведено содержимое файла с описанием типа Authentication, который реализует службу аутентификации:
//AuthenticationModule.cs
using System;
namespace AuthenticationModule
{public class Authentication: MarshalByRefObject
	{	public String GetAccess(String login,String password)
		{	if(login=="nick"&&password=="qwerty")
				return "Доступ разрешен";
			else
				return "Доступ запрещен";
		}
	}
}

   Этот файл с описание компилируется в библиотеку с именем AuthenticationModule. Как видно реализация типа очень простая. Тип содержит только один метод GetAccess, который получает в качестве параметров имя пользователя (login) и пароль (password), сравнивает их с заранее определенными значениями и возвращает строку, которая сообщает о разрешении или запрещении доступа. Главной особенностью типа Authentication является то, что он наследуется от типа System.MarshalByRefObject, который позволяет передаваться ему по ссылке.
   Ниже приведено содержимое исходного файла, в котором реализуется программа сервера:
//Server.cs
using System;
using System.Runtime.Remoting;
namespace Server
{	class Server
	{	static void Main(string[] args)
		{	RemotingConfiguration.Configure("Server.exe.config");
			Console.WriteLine("Press Enter to exit");
			Console.ReadLine();
		}
	}
}


   Представленный исходный файл компилируется в исполняемый файл. В файле Server.cs описан класс Server, который содержит единственный метод Main, с которого начинается выполнения программы. В этом методе выполняется конфигурирования инфраструктуры .NET Remoting, путем выполнения метода RemotingConfiguration.Configure(), который читает файл конфигурации “Server.exe.config”. В следующих двух строках выводится сообщение и ожидается нажатие клавиши для завершения программы. В данном примере настройка распределенного приложения осуществляется с помощью конфигурационного файла, что очень сильно упрощает само приложение и облегчает с ним работу, так как если понадобиться изменить какие-либо настройки, то не надо перекомпилировать само приложение. Ниже приведено содержимое файла конфигурации Server.exe.config:

< configuration>
  < system.runtime.remoting>
    < application name="Server">
      < service>
        < wellknown 
          mode="SingleCall" 
          type="AuthenticationModule.Authentication, AuthenticationModule" 
          objectUri="Authentication.rem" />
      </service>
      < channels>
        <channel ref="tcp" port="8008" />
      </channels>
    </application>
  </system.runtime.remoting>
</configuration>


   Как видно этот файл представляет собой описание в формате XML. В этом файле указывается, что выполняется настройка на стороне сервера (тег ), который предоставляет объект с серверной активизацией (тег ) в режиме SingleCall (параметр mode=”SingleCall”), здесь же указывается имя дистанцируемого типа и имя сборки, в которой он находится. Тегом определяется тип канала передачи сообщений и номер порта, на котором будет доступен сервер. Содержимое файла с исходным кодом клиента выглядит следующим образом:

//Client.cs
using System;
using System.Runtime.Remoting;
using AuthenticationModule;
namespace Client
{	class Client
	{	static void Main(string[] args)
		{	String login,password,answer;
				RemotingConfiguration.Configure("Client.exe.config");
				Authentication Auth = new Authentication();
				Console.WriteLine("Введите логин:");
				login=Console.ReadLine();
				Console.WriteLine("Введите пароль:");
				password=Console.ReadLine();
				answer=Auth.GetAccess(login,password);
				Console.WriteLine(answer);
				Console.ReadLine();
		}
	}
}



   В файле Client.cs описан класс Client, который также содержит единственный метод Main. В этом методе сначала выполняется настройка инфраструктуры .NET Remoting, таким же образом как и на сервере, а потом выполняется привязка к удаленному объекту Authentication, которая выполняется неявно, как будто создается локальный объект с помощью операции new. После привязки запрашиваются имя и пароль, вызывается удаленный метод Auth.GetAccess (login, password) и выводится результат попытки доступа. Ниже приведен конфигурационный файл клиентского приложения client.exe.config:

< configuration>
  < system.runtime.remoting>
    < application>
      < client>
        < wellknown 
          type="AuthenticationModule.Authentication, Authentication" 
     url="tcp://localhost:8008/AuthenticationModule/Authentication.rem" />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>



   Этот файл по структуре соответствует серверному. В нем указывается, что это конфигурация на стороне клиента (тег ), таким же образом указывается тип, к которому будет выполняться доступ из клиента (параметр type). Небольшим отличием является то, что тип канала и номер порта указываются непосредственно в пути доступа к удаленному объекту (параметр url). Таким образом из данного примера видно, что с помощью .NET Remoting достаточно просто реализуется взаимодействие с удаленными объектами и распределенные приложения могут очень просто настраиваться с помощью конфигурационных файлов.


Литература


1. Таненбаум Э., М. ван Стеен «Распределенные системы. Принципы и парадигмы». – СПб: Питер, 2003. – 877 с.

2. Маклин С., Нафтел Дж., Уильямс К. «Micrsoft .NET Remoting». – М: Издательско-торговый дом «Русская редакция», 2003. – 384 с.

3. Троелсен Э. «C# и платформа .NET. Библиотека программиста». – СПб: Питер, 2004. – 796 с.

4. Рихтер Дж. «Программирование на платформе Microsoft .NET Framework». – М: Издательско-торговый дом «Русская редакция», 2003. – 512 с.