В дистанционной работе.NET, каково различие между RemotingConfiguration. RegisterWellKnownServiceType и RemotingServices. Маршал?

вы можете сделать:

for k in ax.get_xmajorticklabels():
    if some-condition:
        k.set_color(any_colour_you_like)

draw()
17
задан David Basarab 29 January 2009 в 21:13
поделиться

3 ответа

Это - то, что я нашел.

RemotingConfiguration.RegisterWellKnownServiceType(typeof(FooRemoting), 
          serverName, WellKnownObjectMode.Singleton);

RegisterWellKnownServiceType создаст объект и сделает его Singleton любому клиенту, который использует его, но ссылка сервером не создается. Объект не создается, пока клиент не просит его, и тот же объект используется для любых других клиентов.

RemotingServices.Marshal(foo);

Маршал зарегистрирует объект, который был создан сервером, в этом случае сервис окон. Затем сервер будет затем иметь ссылку на объект, и клиенты используют тот же объект.

Моя проблема использовала Маршала для регистрации объекта ремоутинга. Со временем объект ремоутинга будет исчезать, чтобы клиенты использовали, т.е. больше на объекте ремоутинга. Сервис все еще сохранил бы свою ссылку. Затем я попробовал RegisterWellKnownServiceType, и клиенты продолжают получать корректную ссылку, однако я не мог заставить сервис иметь ссылку на тот же объект.

решение переопределяет объект ремоутинга в этом случае FooRemoting. Если бы я переопределил InitializeLifetimeService и возвратил пустой указатель, то клиент никогда не терял бы соединение, и сервис будет, сохранить соединение.

public override object InitializeLifetimeService()
{
    //return base.InitializeLifetimeService();
    return null;
}

, Чтобы сохранить объект созданным сервисом и иметь клиент для использования того же объекта, необходимо использовать

RemotingServices.Marshal(foo);

и переопределить InitializeLifetimeService для возврата пустого указателя.

20
ответ дан 30 November 2019 в 12:01
поделиться

Я провел один эксперимент с RemotingServices.Marshal, подобный этому

Удаленный компонент, размещенный в Windows Exe. Код Exe:

Form1_Load(object sender, EventArgs e)
{
   RemotingConfiguration.Configure("path of the config file");
   RemoteClass obj = new RemoteClass();
   obj.MyVal =100;

   RemotingServices.Marshal(obj);
}


public RemoteClass: MarshalByRefObj
{
   static int Counter;
   public RemoteClass()
   {
      Counter++;
   }

   int _MyVal =0;
  public int MyVal
 {
    get
   {
      return _MyVal;
   }
   set
   {
      _MyVal = value;
   }
 }       
}

Теперь в коде на стороне клиента

button1_click()
{
  RemoteClass obj = Activator.GetObject(typeof(RemoteClass), "object URI");
  if(RemotingServices.IsTransparentProxy(obj))
  {
      MessageBox.Show(obj.Myval.ToString());
  }
}

он отобразит сообщение как 0, а не 100. Если вы поместите точку останова в конструктор RemoteClass, вы увидите, что конструктор вызывается 2 раза

  1. Когда объект RemoteClass создается в самой Службе
  2. Когда клиент выполняет вызов свойства MyVal.

Я думаю, что RemotingServices.Marshal не имеет ничего общего с единственным экземпляром. Даже если вы используете только RemotingConfiguration.Configure и переопределите InitializeLifetimeService так, чтобы он возвращал null, будет достаточно для размещения удаленного компонента.

1
ответ дан 30 November 2019 в 12:01
поделиться

Можно разоблачить MarshalByRefObjects, которые имеют параметрические конструкторы над удалением, а пользователи класса могут иметь дело только с его интерфейсом.

Я создал небольшое доказательство проекта концепции. В нем есть 3 проекта: Сервер, Клиент и Ядро. Сервер и Клиент оба ссылаются на Core, но не ссылаются друг на друга.

В ядре мы определяем сервисный интерфейс:

namespace Core
{
    public interface ICountingService
    {
        int Increment();
    }
}

Сервер определяет конкретную реализацию, на которую клиент не имеет ссылки:

namespace Server
{
    public class CountingService : MarshalByRefObject, ICountingService
    {
        private static int _value = 0;

        public CountingService(int startValue)
        {
            _value = startValue;
        }

        public int Increment()
        { // not threadsafe!
            _value++;
            return _value;
        }
    }
}

Важные биты, на которые следует обратить внимание, это то, что у него есть конструктор с параметром, это MarshalByRefObject, и он реализует интерфейс в проекте ядра.

Проект сервера - это консольное приложение, которое устанавливает канал удалённого доступа (произвольно по HTTP для данного примера), создаёт сервис и регистрирует его с помощью удалённого доступа:

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;

namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpServerChannel serverChannel = new HttpServerChannel(8234);
            ChannelServices.RegisterChannel(serverChannel, false);

            // Following line won't work at runtime as there is no parameterless constructor
            //RemotingConfiguration.RegisterWellKnownServiceType(typeof(CountingService),
            //                     "CountingService.rem", WellKnownObjectMode.Singleton);

            CountingService countingService = new CountingService(5);
            RemotingServices.Marshal(countingService, "CountingService.rem");

            Console.WriteLine("Press enter to exit.");
            Console.ReadLine();
        }
    }
}

В приведённом выше коде зарегистрирован URL http://localhost:8234/CountingService.rem, содержащий инстанцированный сервис, который начнёт отсчёт с 5.

Клиент, также консольное приложение, может получить ссылку, используя класс интерфейса:

using System;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using Core;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClientChannel serverChannel = new HttpClientChannel();
            ChannelServices.RegisterChannel(serverChannel, false);

            for (int i = 0; i < 5; i++)
            {
                ICountingService countingService =
                    (ICountingService)Activator.GetObject(typeof(ICountingService),
                    "http://localhost:8234/CountingService.rem");

                int newValue = countingService.Increment();
                Console.WriteLine("Value is " + newValue);
            }

            Console.WriteLine("Press enter to exit.");
            Console.ReadLine();
        }
    }
}

Когда сервер и клиент запущены, он печатает значения от 6 до 10.

Резюме: клиент знает только о интерфейсе; конструктор реализации может иметь параметры; инстанцирование может управляться собственным кодом, а не .NET. Очень полезно при работе с инъекциями зависимостей на основе конструктора с удаленными объектами.

14
ответ дан 30 November 2019 в 12:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: