Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции OOP c#.doc
Скачиваний:
44
Добавлен:
22.09.2019
Размер:
3.38 Mб
Скачать

3.7. Хостинг распределенных приложений

В данном параграфе обсуждаются различные виды размещения (хостинга) серверных компонент распределенных приложений. В качестве примера удаленного класса на протяжении параграфа будет использоваться простой класс BSUIR.Calculator, который скомпилирован в сборку с именем calc.dll.

using System;

namespace BSUIR {

public class Calculator: MarshalByRefObject {

public Calculator() {

log("Calculator constructor");

}

public double Add(double x, double y) {

log("Add " + x + " + " + y);

return x + y;

}

public static void log(string s) {

Console.WriteLine("[{0}]: {1}",

AppDomain.CurrentDomain.FriendlyName, s);

}

}

}

Обратите внимание, что в компоненте не выделен интерфейс. Для предоставления клиенту метаданных компонента будем просто передавать сборку с компонентом клиенту.

Клиент, используемый в примерах, достаточно стандартен:

using System;

using System.Runtime.Remoting;

using BSUIR;

class CalcClient {

public static void Main() {

string filename = "client.exe.config";

RemotingConfiguration.Configure(filename);

Calculator c = new Calculator();

Console.WriteLine(c.Add(3, 4));

}

}

Настройка Remoting на стороне клиента выполняется при помощи файлов конфигурации, которые будут описаны ниже.

В Remoting серверные компоненты распределенных приложений могут использовать хостинг на основе консольных приложений или приложений Windows Forms, хостинг Windows-сервиса или хостинг при помощи веб-сервера Internet Information Server (IIS).

Хостинг на основе консольных приложений или приложений Windows Forms прост в реализации. Однако такой вид хостинга имеет ряд недостатков. В частности, необходим ручной запуск приложения-сервера, затруднено решение проблем аутентификации и логирования.

Рассмотрим хостинг компонент с использованием Windows-сервиса. В .NET Framework пользовательский Windows-сервис – это класс, производный от ServiceProcess.ServiceBase. Обычно в классе требуется переписать виртуальный метод onStart() для выполнения некоторых полезных действий. В следующем листинге приведена «заготовка» пользовательского сервиса:

using System;

using System.ServiceProcess;

namespace WindowsService {

public class DummyService : ServiceBase {

public static string SVC_NAME = "Some dummy service";

public DummyService() {

// в конструкторе установим свойство – имя сервиса

this.ServiceName = SVC_NAME;

}

static void Main() {

//стартуем сервис

ServiceBase.Run(new DummyService());

}

protected override void OnStart(string[] args) {

// полезный код сервиса

}

protected override void OnStop() {

// действия сервиса перед остановкой

}

}

}

Для установки пользовательского сервиса в систему требуется создать специальный класс-инсталлятор. Этот класс будет обрабатываться утилитой установки installutil.exe, которая входит в состав .NET Framework. В следующем листинге показан простой класс-инсталятор, настраивающий сервис на автоматический старт при запуске системы:

using System.Configuration.Install;

using System.ServiceProcess;

using System.ComponentModel;

using WindowsService;

[RunInstallerAttribute(true)]

public class MyProjectInstaller: Installer {

private ServiceInstaller serviceInstaller;

private ServiceProcessInstaller processInstaller;

public MyProjectInstaller() {

processInstaller = new ServiceProcessInstaller();

serviceInstaller = new ServiceInstaller();

processInstaller.Account = ServiceAccount.LocalSystem;

serviceInstaller.StartType =

ServiceStartMode.Automatic;

serviceInstaller.ServiceName = DummyService.SVC_NAME;

Installers.Add(serviceInstaller);

Installers.Add(processInstaller);

}

}

Два файла – файл с кодом сервиса и файл с классом-инсталлятором – требуется скомпилировать в одну сборку (например, CustomWinServ.exe). Для установки сервиса выполняется следующая команда:

installutil CustomWinServ.exe

В случае успешной установки сервис ведет себя как любой стандартный сервис, он допускает управление (старт-стоп) при помощи оснастки администрирования (MMC).

Разрабатываемый сервис имеет возможность записывать информацию в Журнал событий (Event Log) системы. Для этого достаточно объявить в классе-сервисе статическую переменную типа System.Diagnostics.EventLog и использовать ее метод WriteEntry().

В листинге представлен класс-сервис для BSUIR.Calculator:

using System;

using System.Diagnostics;

using System.ServiceProcess;

using System.Runtime.Remoting;

namespace WindowsService {

public class RemotingService : ServiceBase {

private static EventLog evt = new EventLog("Application");

public static string SVC_NAME = "Remoting Sample Service";

public RemotingService() {

this.ServiceName = SVC_NAME;

}

static void Main() {

evt.Source = SVC_NAME;

evt.WriteEntry("Remoting Service intializing");

ServiceBase.Run(new RemotingService());

}

protected override void OnStart(string[] args) {

evt.WriteEntry("Remoting Service started");

String filename = "WinServ.exe.config";

RemotingConfiguration.Configure(filename);

}

protected override void OnStop() {

evt.WriteEntry("Remoting Service stopped");

}

}

}

Класс-инсталятор остается практически без изменений (используется имя класса-сервиса RemotingService). Два файла компилируются в сборку CustomWinServ.exe, к которой подключается сборка calc.dll.

Конфигурационный файл CustomWinServ.exe.config имеет такой вид:

<configuration>

<system.runtime.remoting>

<application>

<channels>

<channel ref="http" port="1234" />

</channels>

<service>

<wellknown mode="Singleton"

type="BSUIR.Calculator, Calc"

objectUri="Calculator.soap" />

</service>

</application>

</system.runtime.remoting>

</configuration>

Соответствующий конфигурационный файл для клиента:

<configuration>

<system.runtime.remoting>

<application>

<channels>

<channel ref="http" port="0" />

</channels>

<client>

<wellknown type="BSUIR.Calculator, Calc"

url="http://localhost:1234/Calculator.soap" />

</client>

</application>

</system.runtime.remoting>

</configuration>

Хостинг с использованием IIS обладает рядом преимуществ по сравнению с другими видами хостинга. В частности, IIS может быть сконфигурирован для обеспечения аутентификации пользователей удаленного компонента, а также для шифрования серверного трафика. Необходимо понимать, что IIS-хостинг накладывает ряд ограничений на конфигурацию удаленного класса. Допустимо использование только HTTP-канала (возможно, с нестандартным форматером). По сравнению с другими видами хостинга, использование IIS является менее производительным решением.

Общая схема IIS-хостинга проста:

  1. Удаленные типы размещаются в отдельной сборке (библиотеке классов).

  2. При помощи оснастки IISAdmin создается виртуальная директория, соответствующая серверной части распределенного приложения.

  3. В поддиректорию bin помещается библиотека классов.

  4. В виртуальной директории размещается конфигурационный файл, который называется web.config.

Создадим при помощи оснастки IISAdmin виртуальный каталог. Виртуальный каталог является частью URL и соответствует некому физическому каталогу на сервере. Например, в URL вида http://host_name/directory_name виртуальный каталог – это directory_name. Ему может соответствовать физический каталог c:\somedirectory. Стандартному URL http://host_name/ по умолчанию соответствует каталог c:\inetpub\wwwroot. После запуска оснастки IISAdmin (Пуск Программы Администрирование Internet Information Services) требуется выбрать пункт Веб-узел по умолчанию, в контекстном меню пункта выбрать Создать → Виртуальный каталог. Запустится Мастер создания виртуального каталога. Требуется указать имя для каталога (укажем remote) и соответствующую каталогу директорию на диске (c:\rem). В сформированной виртуальной директории необходимо создать подкаталог bin и поместить в него сборку с удаленным типом. Альтернативное решение заключается в размещении сборки в GAC, но помните, что для доступа к сборке будет необходимо использовать сильное имя.

Конфигурационный файл web.config, размещенный в каталоге c:\rem, выглядит следующим образом:

<configuration>

<system.runtime.remoting>

<application>

<service>

<wellknown mode="Singleton"

type="BSUIR.Calculator, Calc"

objectUri="Calculator.soap" />

</service>

</application>

</system.runtime.remoting>

</configuration>

В конфигурационном файле отсутствует описание канала (ISS-хостинг подразумевает HHTP и стандартный порт). При необходимости изменить форматер по умолчанию для HTTP-канала описание канала должно присутствовать. Также при указании концевой точки обязательно должен быть записан суффикс soap.

Конфигурационный файл клиента выглядит следующим образом:

<configuration>

<system.runtime.remoting>

<application>

<client>

<wellknown type="BSUIR.Calculator, Calc"

url="http://localhost/remote/Calculator.soap" />

</client>

</application>

</system.runtime.remoting>

</configuration>