Раздел «Технологии программирования».RemotingNET:

.NET Remoting

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

Однако кажется очень привлекательной идея совместной работы независимых приложений, запущенных на разных машинах. Это может быть реализовано многими способами. Например, два приложения могут открыть TCP-соединение и обмениваться необходимой информацией. Многие языки программирования предоставляют такую возможность. Однако существенным недостаком такого подхода является то, что приложения должны разрабатывать собственный протокол взаимодействия. Часто также предоставляется возможность передачи целых объектов, при этом они должны быть объявлены как [Serializable]. .NET Remoting предлагает простой и изящный подход к решению данной проблемы.

Давайте разберемся, что же такое Remoting. В двух словах, клиент имеет возможность исполнять методы какого-то класса на машине сервера. Т.е. единственное, что нам нужно сделать, это получить ссылку на экземпляр данного класса и дальше мы можем работать с ним обычными способами, не забывая, однако, что все методы данного класса будут исполняться на удаленной машине.

Теперь давайте разберемся, какие средства Remoting предоставляет нам .NET. Вот пример простейшей программы, демонстрирующей работу с распределенными системами:

Это объявление того самого класса, ссылку на который получает клиент. Он содержит единственный метод Hello(), который и будет вызывать клиент. Следует отметить, что этот класс обязательно должен наследоваться от класса MarshalByRefObject.

using System;

namespace Test
{
   public class ClassForRemoting : MarshalByRefObject
   {
      public ClassForRemoting()
      {
      }

      public void Hello()
      {
         Console.WriteLine("Hello!");
      }
   }
}

Теперь посмотрим, как выглядит сервер, предоставляющий класс для удаленного использования. Вся его работа состоит из двух частей:

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace Test
{
   public class Server
   {
      public Server()
      {
         //создаем канал, по которому будут передаваться данные
         TcpServerChannel tc = new TcpServerChannel (4242);
         //регистрируем канал; можно считать это частью создания канала :)
         ChannelServices.RegisterChannel (tc);
         //теперь регистрируем объект, который будет виден клиенту
         RemotingConfiguration.RegisterWellKnownServiceType (typeof(ClassForRemoting), "CFR",
            WellKnownObjectMode.Singleton);
      }
   }
}

И, наконец, клиент. Его работа также состоит из двух частей:

using System;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace Test
{
   public class Client
   {
      public Client()
      {
         //создание и регистрация канала
         ChannelServices.RegisterChannel (new TcpClientChannel());
         //получение ссылки на объект класса ClassForRemoting
         ClassForRemoting h = (ClassForRemoting) Activator.GetObject (typeof(ClassForRemoting),
            "tcp://localhost:4242/CFR");
         h.Hello1();
      }
   }
}

Для демонстрации взаимодействия клиента и сервера необходимо создать экземпляр класса Server, затем экземпляр класса Client. И после этого мы должны увидеть строку "Hello!" на экране сервера.

Тонкие моменты.

1. Возникает вопрос, в какой момент создается экземпляр класса ClassForRemoting? Ответ таков: когда клиент получает ссылку на объект, создания объекта на стороне сервера не происходит. Объект создается только лишь при вызове методов класса.

2. Один из параметров функции (последний)

RemotingConfiguration.RegisterWellKnownServiceType (typeof(ClassForRemoting), "CFR",
            WellKnownObjectMode.Singleton);

определяет поведение объекта после того, как вызванный метод закнчил свою работу. Если класс для удаленного доступа объявлен как WellKnownObjectMode.Singleton, создание объекта происходит единожды, при вызове первого метода. При вызове дальнейших методов используется та же копия. В противоположность этому, если параметр установлен в WellKnownObjectMode.SingleCall, создание объекта происходит при каждом вызове его методов, а после окончания работы метода происходит удаление объекта.

3. Если в течение некоторого времени (по умолчанию, 5 минут) не происходило вызовов методов объекта, считается, что по непонятным причинам ссылка на объект была утеряна клиентом и поэтому объект помечается как неиспользуемый (т.е. в любой момент может быть удален сборщиком мусора). Чтобы этого не происходило, необходимо переопределить метод в классе ClassForRemoting, непосредственно задав необходимые времена:

public override object InitializeLifetimeService()
{
   ILease lease = (ILease)base.InitializeLifetimeService();
   if (lease.CurrentState == LeaseState.Initial)
   {
      lease.InitialLeaseTime = TimeSpan.FromMilliseconds(time);
      lease.SponsorshipTimeout = TimeSpan.FromMilliseconds(time);
      lease.RenewOnCallTime = TimeSpan.FromMilliseconds(time);
   }
   return lease;
}

Как видим, время жизни объекта управляется тремя временами. Можно детально изучить влияние этих параметров, а можно просто сделать так:

public override object InitializeLifetimeService()
{
   return null;
}

В этом случае объект будет жить вечно.

4. Не существует адекватного способа вызова контструктора класса ClassForRemoting с параметрами, поэтому необходимо так продумать логику программы, чтобы параметры не требовались.

5. Если методы класса ClassForRemoting в качестве параметров используют классы (а не примитивные типы), то эти классы должны иметь модификатор [Serializable].

Ссылки.

http://www.rsdn.ru/article/dotnet/inside_remoting1.xml http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemruntimeremoting.asp

-- IgorKvasov? - 22 May 2005

Attachment sort Action Size Date Who Comment
IngoRammer-Advanced.NETRemoting.pdf manage 2877.5 K 22 May 2005 - 21:46 IgorKvasov? Подробная документация по .NET Remoting (English)
Test.rar manage 24.2 K 22 May 2005 - 21:49 IgorKvasov? Исходый код приложения-демонстрации .NET Remoting