Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> повторный вызов RegisterActivatedClientType 
:(
    Опции темы
Grambler
Дата 16.5.2007, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 22.12.2006

Репутация: нет
Всего: нет



Код

ChannelServices.RegisterChannel(chanel, false);
RemotingConfiguration.RegisterActivatedClientType(typeof(GTServer.GTRemoteServer),
                   string.Format("tcp://{0}:{1}", Conf.Config.ClientGT.RemoteIP, Conf.Config.ClientGT.RemotePort));        


проблема в том, что если допустим надо поменять Conf.Config.ClientGT.RemoteIP, Conf.Config.ClientGT.RemotePort
то при повторной регистрации вылетает следующий эсепшен

Попытка перенаправить активацию для типа 'GTServer.GTRemoteServer, ServerGTAssembly', которая уже перенаправлена


M
Дрон
Вторую тему, с точно таким же вопросом, но без ответов, я удалил. Пожалуйста, не создавайте дубликатов своих тем.


Это сообщение отредактировал(а) Дрон - 17.5.2007, 11:03
PM MAIL   Вверх
tol05
Дата 16.5.2007, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 6
Всего: 170



Смотри, пример с MSDN (http://msdn2.microsoft.com/en-us/library/h...x8b(VS.80).aspx)
Код

public static void Main() { 

        ChannelServices.RegisterChannel(new TcpChannel());

        RemotingConfiguration.RegisterActivatedClientType(typeof(HelloServiceClass), "tcp://localhost:8082");

        HelloServiceClass service = new HelloServiceClass();

        if(service == null) 
       {
            Console.WriteLine("Could not locate server.");
            return;
        }

а ты предлагаешь сделать так:
Код

public static void Main() { 

        ChannelServices.RegisterChannel(new TcpChannel());

        RemotingConfiguration.RegisterActivatedClientType(typeof(HelloServiceClass), "tcp://localhost:8082");

        HelloServiceClass service = new HelloServiceClass();

        RemotingConfiguration.RegisterActivatedClientType(typeof(HelloServiceClass), "tcp://home:9999");

       //куда системе обращаться за HelloServiceClass? к tcp://localhost:8082 или к tcp://home:9999
        HelloServiceClass service2 = new HelloServiceClass();

        if(service == null) 
       {
            Console.WriteLine("Could not locate server.");
            return;
        }


Вопрос отпал? smile

Попробуй вот что:
RemotingConfiguration.RegisterActivatedClientType(...) убери ввобще, а работай через Activator/
пример с MSDN превращается в 
Код

public static void Main() { 

        ChannelServices.RegisterChannel(new TcpChannel());

        object[] attr = {new UrlAttribute(string.Format("tcp://{0}:{1}", Conf.Config.ClientGT.RemoteIP, Conf.Config.ClientGT.RemotePort))}
        HelloServiceClass service = Activator.CreateInstance(typeof(HelloServiceClass), attr);

        if(service == null) 
       {
            Console.WriteLine("Could not locate server.");
            return;
        }

        //меняешь Conf.Config.ClientGT.RemoteIP, Conf.Config.ClientGT.RemotePort

        object[] attr2 = {new UrlAttribute(string.Format("tcp://{0}:{1}", Conf.Config.ClientGT.RemoteIP, Conf.Config.ClientGT.RemotePort))}
        HelloServiceClass service2 = Activator.CreateInstance(typeof(HelloServiceClass), attr2);

        if(service2 == null) 
       {
            Console.WriteLine("Could not locate server.");
            return;
        }
}


Это сообщение отредактировал(а) tol05 - 16.5.2007, 16:14


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
Grambler
Дата 16.5.2007, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 22.12.2006

Репутация: нет
Всего: нет



все гениальное просто ? ))
PM MAIL   Вверх
Grambler
Дата 16.5.2007, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 22.12.2006

Репутация: нет
Всего: нет



не работает

Код

object[] attr = {new UrlAttribute(string.Format("tcp://{0}:{1}", 
                    Conf.Config.ClientGT.RemoteIP, Conf.Config.ClientGT.RemotePort))};
 remServer = (GTServer.GTRemoteServer)Activator.CreateInstance(typeof(GTServer.GTRemoteServer), attr);

ексепшен
{"Конструктор для типа \"GTServer.GTRemoteServer\" не найден."}
PM MAIL   Вверх
tol05
Дата 16.5.2007, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 6
Всего: 170



Покажи весь код. Завтра я тебе его верну исправленным. Сегодня не успею.
И на будущее: удаленный объект всегда должен иметь public конструктор по умолчанию (без параметров)
это аксиома для ремоутинга!

Только так ремоутинг и создает удаленные объекты! Другого способа не бывает!
 smile 



--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
Grambler
Дата 17.5.2007, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 22.12.2006

Репутация: нет
Всего: нет



Цитата

Покажи весь код. Завтра я тебе его верну исправленным. Сегодня не успею.
И на будущее: удаленный объект всегда должен иметь public конструктор по умолчанию (без параметров)
это аксиома для ремоутинга!

конструктор разумеется есть 

привожу код тестового проекта 
удаленный класс
Код

    public class RemoteMessageObject: MarshalByRefObject
    {        
        public RemoteMessageObject()
        {
            Count++;
            Console.WriteLine("Constructing RemoteMessageObject! count of RemoteMessageObject = {0}", Count);
            Console.WriteLine("count of RemObject = {0}", remObject.Count);
        }
         private static int Count;

        private static MyRemoteClass remObject = new MyRemoteClass();

        public MyRemoteClass RemObject
        {
            get { return remObject; } //RemoteMessageObject.remObject
            //set { RemoteMessageObject.remObject = value; }
        }
        // This method displays an input string 
        // from the caller.
        public void DisplayMessage(string msg)
        {
            //Console.WriteLine("Message is: {0}, count={1}", msg, Count);
            remObject.DisplayMessage(msg);
        }

        // This method returns a value to the
        // caller.
        public string ReturnMessage()
        {
            //return string.Format("Hello from the server! {0}", Count);
            return remObject.ReturnMessage();
        }
    }

public class MyRemoteClass: MarshalByRefObject
    {
        public MyRemoteClass()
        {
            count++;
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 9001);
            listener.Bind(localEndPoint);
            listener.Listen(100);
            items.Add("1");
            items.Add("2");
            items.Add("3");
            Console.WriteLine("Constructing MyStaticClass! count = {0}", count);
        }
        private static int count;

        public int Count
        {
            get { return count; }
            set { count = value; }
        }
        public void DisplayMessage(string msg)
        {
            Console.WriteLine("Message is: {0}, count ={1}", msg, count);
        }
        public string ReturnMessage()
        {
            return string.Format("Hello from MyRemoteClass! {0}", count);
        }
        static private ArrayList items = new ArrayList();

        public ArrayList Items
        {
            get { return items; }
            set { items = value; }
        }
        public int GetItemsCount()
        {
            return items.Count;
        }

        [NonSerialized]
        private Socket listener;

        public Socket Listener
        {
            get { return listener; }
            //set { listener = value; }
        }

    }



сервер
Код

namespace TCPSimpleRemoteObjectServer
{
    class SimpleObjServer
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Server started! *****");
            Console.WriteLine("Hit enter to end");
            //RemotingConfiguration.Configure("TCPSimpleRemoteObjectServer.exe.config", false);
            // Create a new TcpChannel
            TcpChannel c = new  TcpChannel(8008);
            ChannelServices.RegisterChannel(c, false);            
            RemoteMessageObject remMesObj = new RemoteMessageObject();
            // Register a 'well-known' object.
            //RemotingConfiguration.RegisterWellKnownServiceType(
            //    typeof(SimpleRemotingAsm.RemoteMessageObject),
            //    "RemoteMsgObj.rem",
            //    WellKnownObjectMode.Singleton);            

            // Register a 'CAO' object.
            RemotingConfiguration.RegisterActivatedServiceType(typeof(SimpleRemotingAsm.RemoteMessageObject));
            Console.WriteLine("remMesObj.RemObject.GetItemsCount = {0}", 
                remMesObj.RemObject.GetItemsCount());
            Console.ReadLine();        
        }
    }
}


клиент:
Код

namespace TCPSimpleRemoteObjectClient
{
    class SimpleObjClient
    {
        static void Main(string[] args)
        {
            //RemotingConfiguration.Configure("TCPSimpleRemoteObjectClient.exe.config", false);
            //// Create a new TcpChannel
            TcpChannel c = new TcpChannel();
            ChannelServices.RegisterChannel(c, false);
            //// Get a proxy to remote object.
            //object remoteObj = Activator.GetObject(
            //    typeof(SimpleRemotingAsm.RemoteMessageObject),
            //    "tcp://localhost:32469/RemoteMsgObj.rem");
            //RemoteMessageObject simple = (RemoteMessageObject)remoteObj;

            //RemotingConfiguration.RegisterActivatedClientType(typeof(SimpleRemotingAsm.RemoteMessageObject),
            //    "tcp://localhost:8008");

            //RemoteMessageObject simple = new RemoteMessageObject();

            object[] attr = { new UrlAttribute(string.Format("tcp://{0}:{1}", "127.0.0.1", 8008)) };
            RemoteMessageObject simple = (SimpleRemotingAsm.RemoteMessageObject)Activator.CreateInstance(typeof(SimpleRemotingAsm.RemoteMessageObject), attr);             

            Console.WriteLine("simple.RemObject.Count={0}", simple.RemObject.Count);//
            //Console.WriteLine("simple.RemObject.Items.Count = {0}", simple.RemObject.Items.Count);
            //Console.WriteLine("{0}", simple.RemObject.GetItemsCount());
            simple.DisplayMessage("Hello from the client!");
            simple.RemObject.DisplayMessage("Hello from the simple.RemObject!");
            Console.WriteLine("Server says: {0}", simple.ReturnMessage());
            Console.WriteLine("Client started!  Hit enter to end");
            Console.ReadLine();

            Console.WriteLine("Client Disposed");
        }
    }
}


после замены 
Код

RemotingConfiguration.RegisterActivatedClientType(typeof(SimpleRemotingAsm.RemoteMessageObject),
            "tcp://localhost:8008");
RemoteMessageObject simple = new RemoteMessageObject();

на
Код

object[] attr = { new UrlAttribute(string.Format("tcp://{0}:{1}", "127.0.0.1", 8008)) };
RemoteMessageObject simple = (SimpleRemotingAsm.RemoteMessageObject)Activator.CreateInstance(typeof(SimpleRemotingAsm.RemoteMessageObject), attr);             

вылетает эксепшен "Конструктор для типа \"тип" не найден."}

Это сообщение отредактировал(а) Grambler - 17.5.2007, 09:55
PM MAIL   Вверх
arilou
Дата 17.5.2007, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Великий МунаБудвин
****


Профиль
Группа: Экс. модератор
Сообщений: 2646
Регистрация: 15.7.2004
Где: город-герой Минск

Репутация: 3
Всего: 61



Grambler, пардон за вопрос, а почему бы не настроить весь ремоутинг через .config файл и не париться?


--------------------
user posted imageuser posted image
PM WWW ICQ   Вверх
Grambler
Дата 17.5.2007, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 22.12.2006

Репутация: нет
Всего: нет



Цитата

Grambler, пардон за вопрос, а почему бы не настроить весь ремоутинг через .config файл и не париться?


можно конечно, просто есть необходимость вынести настройки ремоутинга в общие настройки программы
но при их изменении (ip, port) приходится перезапускать программу
PM MAIL   Вверх
tol05
Дата 17.5.2007, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 6
Всего: 170



Но если их не вынести в конфиг, то тогда 
Grambler, 
Цитата(Grambler @  17.5.2007,  12:54 Найти цитируемый пост)
при их изменении (ip, port)

прийдется перекомпиливать приложение и заново клиентам развозить smile

А теперь по твоему коду. Раз обещал, надо фиксать. 
Устал я, пока понял, в чем причина. Их даже несколько.

Во-первых, я забыл, что Activator позволяет создавать инстансы не только для ремоутинга и дал тебе не ту перегрузку метода smile
вот правильный вариант (по крайней мере рабочий)
Код

object[] attrs = { new UrlAttribute(string.Format("tcp://{0}:{1}", "127.0.0.1", 8008)) };

        ObjectHandle handle =
                 Activator.CreateInstance("SimpleRemotingAsm", "SimpleRemotingAsm.RemoteMessageObject", attrs);
        if(handle == null)
        {
          Console.WriteLine("could not locate server");
          return;
        }
        RemoteMessageObject simple = (RemoteMessageObject)handle.Unwrap();


во-вторых, ты тоже оказывается не промах. Почему ты не упомянул, что юзаешь ДВА удаленных объекта, а не один? А второй - тоже сокет использует!!! И настройки не меняются (9001 порт при каждом вызове насилуется). Вот эксепшен и вылетает. Ты смотри не только сообщение об эксепшене, но и его свойство InnerException!

Как только я закоментал 
Код

// private static MyRemoteClass remObject = new MyRemoteClass();

и все, что с ним связано, все заработало.
Потом раскоментал, закоментал этот долбанный сокет на 9001 порт, тоже работает.
вот весь код, без комментов и мусора. Только в объекте я комменты оставил.
удаленный объект
Код

public class RemoteMessageObject :MarshalByRefObject
  {
    public RemoteMessageObject()
    {
      Count++;
      Console.WriteLine("Constructing RemoteMessageObject! count of RemoteMessageObject = {0}", Count);
      //Console.WriteLine("count of RemObject = {0}", remObject.Count);
    }
    private static int Count;

    private static MyRemoteClass remObject = new MyRemoteClass();

    //public MyRemoteClass RemObject
    //{
    //  get { return remObject; } //RemoteMessageObject.remObject
    //  //set { RemoteMessageObject.remObject = value; }
    //}
    // This method displays an input string 
    // from the caller.
    public void DisplayMessage(string msg)
    {
      Console.WriteLine("Message is: {0}, count={1}", msg, Count);
      //remObject.DisplayMessage(msg);
    }

    // This method returns a value to the
    // caller.
    public string ReturnMessage()
    {
      return string.Format("Hello from the server! {0}", Count);
      //return remObject.ReturnMessage();
    }
  }

  public class MyRemoteClass :MarshalByRefObject
  {
    public MyRemoteClass()
    {
      count++;
      //listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      //IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 9001);
      //listener.Bind(localEndPoint);
      //listener.Listen(100);
      items.Add("1");
      items.Add("2");
      items.Add("3");
      Console.WriteLine("Constructing MyStaticClass! count = {0}", count);
    }
    private static int count;

    public int Count
    {
      get { return count; }
      set { count = value; }
    }
    public void DisplayMessage(string msg)
    {
      Console.WriteLine("Message is: {0}, count ={1}", msg, count);
    }
    public string ReturnMessage()
    {
      return string.Format("Hello from MyRemoteClass! {0}", count);
    }
    static private ArrayList items = new ArrayList();

    public ArrayList Items
    {
      get { return items; }
      set { items = value; }
    }
    public int GetItemsCount()
    {
      return items.Count;
    }

    [NonSerialized]
    private Socket listener;

    public Socket Listener
    {
      get { return listener; }
      //set { listener = value; }
    }

  }


клиент
Код

namespace TCPSimpleRemoteObjectClient
{
    class SimpleObjClient
    {
      static void Main(string[] args)
      {
        TcpChannel c = new TcpChannel();
        ChannelServices.RegisterChannel(c, false);

        object[] attrs = { new UrlAttribute(string.Format("tcp://{0}:{1}", "127.0.0.1", 8008)) };

        ObjectHandle handle =
                 Activator.CreateInstance("SimpleRemotingAsm", "SimpleRemotingAsm.RemoteMessageObject", attrs);
        if(handle == null)
        {
          Console.WriteLine("could not locate server");
          return;
        }
        RemoteMessageObject simple = (RemoteMessageObject)handle.Unwrap();
 
        simple.DisplayMessage("Hello from the client!");
        Console.WriteLine("Server says: {0}", simple.ReturnMessage());
        Console.WriteLine("Client started!  Hit enter to end");
        Console.ReadLine();

        Console.WriteLine("Client Disposed");
      }
   }
}


сервер
Код

class SimpleObjServer
  {
    static void Main(string[] args)
    {
      Console.WriteLine("***** Server started! *****");
      Console.WriteLine("Hit enter to end");
     
      TcpChannel c = new TcpChannel(8008);
      ChannelServices.RegisterChannel(c, false);
      RemoteMessageObject remMesObj = new RemoteMessageObject();
     
      RemotingConfiguration.RegisterActivatedServiceType(typeof(SimpleRemotingAsm.RemoteMessageObject));

      Console.ReadLine();
    }
  }


все. Удачи.

P.S. 
Все никак не могу успокоиться smile Еще раз объясню.
Если просто на сервере создать
RemoteMessageObject remMesObj = new RemoteMessageObject();
RemoteMessageObject remMesObj2 = new RemoteMessageObject();
то это нормально, статическая переменная у тебя, одна на все экземпляры приложения.
Но ты одну эту переменную создаешь на сервере, а другую - на клиенте. А Компьютер - один! поэтому и IP у двух приложений совпадают
Ты попробуй два раза сервер из проводника запустить, тоже самое будет, завалится оно.

Это сообщение отредактировал(а) tol05 - 17.5.2007, 15:50


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
Grambler
Дата 17.5.2007, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 22.12.2006

Репутация: нет
Всего: нет



спасибо за советы
 вечерком буду тестить
PM MAIL   Вверх
Grambler
Дата 18.5.2007, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 22.12.2006

Репутация: нет
Всего: нет



Цитата

Но если их не вынести в конфиг, то тогда 
Grambler, 
Цитата(Grambler @  17.5.2007,  12:54 Найти цитируемый пост)
при их изменении (ip, port)

прийдется перекомпиливать приложение и заново клиентам развозить smile

я как раз и выношу ip, port в настройки, но не в App.config, в общие программы
проблема следующая:
при запуске клиент пытается подключиться, если неудачно, то настройки надо изменить,
но после  изменения подключиться не удается, только перезапуском клиента.

Цитата

Если просто на сервере создать
RemoteMessageObject remMesObj = new RemoteMessageObject();
RemoteMessageObject remMesObj2 = new RemoteMessageObject();
то это нормально, статическая переменная у тебя, одна на все экземпляры приложения.
Но ты одну эту переменную создаешь на сервере, а другую - на клиенте. А Компьютер - один! поэтому и IP у двух приложений совпадают

проверил я твой код
если в клиенте создавать подключение твоим способом 
Код

object[] attrs = { new UrlAttribute(string.Format("tcp://{0}:{1}", "127.0.0.1", 8008)) };
        ObjectHandle handle =
                 Activator.CreateInstance("SimpleRemotingAsm", "SimpleRemotingAsm.RemoteMessageObject", attrs);
        if(handle == null)
        {
          Console.WriteLine("could not locate server");
          return;
        }
        RemoteMessageObject simple = (RemoteMessageObject)handle.Unwrap();

то выполняется конструктор вложенного статического объекта
Код

public MyRemoteClass()
        {
            count++;
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 9001);
            listener.Bind(localEndPoint);
            listener.Listen(100);
            items.Add("1");
            items.Add("2");
            items.Add("3");
            Console.WriteLine("Constructing MyStaticClass! count = {0}", count);
        }

и при создании сокета - ошибка 
если же использовать прием из книжки
Код

RemotingConfiguration.RegisterActivatedClientType(typeof(SimpleRemotingAsm.RemoteMessageObject),
                "tcp://localhost:8008");
            RemoteMessageObject simple = new RemoteMessageObject(); 

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

Цитата

Ты попробуй два раза сервер из проводника запустить, тоже самое будет, завалится оно.

сервер должен быть один, его не может быть много

вывод:
твой пример в книжках по ремоутингу я не видел,
может он не годится ?
похоже, что у тебя создается объект на клиенте а не на сервере,
отсюда и ошибка



PM MAIL   Вверх
tol05
Дата 18.5.2007, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 6
Всего: 170



Цитата(Grambler @  18.5.2007,  09:30 Найти цитируемый пост)
конструктор выполняется только при первом сооздании объекта, при запуске сервера

возьми, поставь в строчке "Count++;" конструктора класса RemoteMessageObject брейкпоинт, закоментай на клиенте Activator.CreateInstance() и все что я написал, поставь свою конструкцию с new. Запусти в отладке сервер, а потом - клиент. Когда будешь запускать клиента - поток остановится - конструктор выполняется и при первом создании (на сервере) и при втором (на клиенте). Как объяснить? Причем, если при втором создании посмотреть в Call Stack, то можно увидеть
Цитата

mscorlib.dll!System.Activator.CreateInstance(System.Type type, bool nonPublic) + 0x43 bytes    

Цитата(Grambler @  18.5.2007,  09:30 Найти цитируемый пост)
похоже, что у тебя создается объект на клиенте а не на сервере

А ты консольный вывод внимательно смотрел? На сервере и клиенте? 
Консоль сервера:
Цитата

***** Server started! *****
Hit enter to end
Constructing MyStaticClass! count = 1
Constructing RemoteMessageObject! count of RemoteMessageObject = 1
Constructing RemoteMessageObject! count of RemoteMessageObject = 2
Message is: Hello from the client!, count=2

Консоль клиента:
Цитата

Constructing MyStaticClass! count = 1
Server says: Hello from the server! Count = 2
Client started!  Hit enter to end

если на клиенте создается, то как сервер это пишет?! Как у него в remMesObj Count становится равным 2?!
Код

object[] attrs = { new UrlAttribute(string.Format("tcp://{0}:{1}", "127.0.0.1", 8008)) };
        ObjectHandle handle =
                 Activator.CreateInstance("SimpleRemotingAsm", "SimpleRemotingAsm.RemoteMessageObject", attrs);
        if(handle == null)
        {
          Console.WriteLine("could not locate server");
          return;
        }
        RemoteMessageObject simple = (RemoteMessageObject)handle.Unwrap();
        if(RemotingServices.IsTransparentProxy(simple))
          Console.WriteLine("The unwrapped object is a proxy.");
        else
          Console.WriteLine("The unwrapped object is not a proxy!");

Цитата

The unwrapped object is a proxy.
Server says: Hello from the server! Count = 2
Client started!  Hit enter to end

Почему Activator.CreateInstance() вызывает статический конструктор второй раз? Смотрел рефлектором. Похоже, что сначала Activator.CreateInstance вызывает у себя метод Assembly.InternalLoad() с хитрыми параметрами, сборка удаленного объекта грузится в домен клиента. И только потом вызывается перегруженный метод Activator.CreateInstance(), который возвращает прокси!

Цитата(Grambler @  18.5.2007,  09:30 Найти цитируемый пост)
сервер должен быть один, его не может быть много

да я просто пример привел, когда на один 9001 порт вешается два выполняющих процесса.  smile 
Цитата(Grambler @  18.5.2007,  09:30 Найти цитируемый пост)
твой пример в книжках по ремоутингу я не видел

а ты уверен, что все книжки по ремоутингу прочитал?  smile А статьи, блоги? Если есть ссылки, кинь, плиз. Почитаю

P.S. Да, Activator действительно сначала грузит класс в память клиента. Но все равно, потом вызывает прокси. В принципе, можно и с ним работать, в конце-концов, если ремоутинг на разных машинах будет, то и порты у них разные smile Или убрать клиента с сервера.
единственное, до чего докопался, так это то. что можно код упростить, не создавать ObjectHandle и UnWrap() не вызывать:
Код

        object[] attrs = { new UrlAttribute(string.Format("tcp://{0}:{1}", "localhost", 8008)) };
        RemoteMessageObject simple = (RemoteMessageObject)Activator.CreateInstance(
          typeof(SimpleRemotingAsm.RemoteMessageObject),
          BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance,
          null,
          null,
          null,
          attrs);
        simple.DisplayMessage("Hello from the client!");


Это сообщение отредактировал(а) tol05 - 18.5.2007, 12:24


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
Grambler
Дата 18.5.2007, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 22.12.2006

Репутация: нет
Всего: нет



Цитата(tol05 @  18.5.2007,  11:39 Найти цитируемый пост)
возьми, поставь в строчке "Count++;" конструктора класса RemoteMessageObject брейкпоинт, закоментай на клиенте Activator.CreateInstance() и все что я написал, поставь свою конструкцию с new. Запусти в отладке сервер, а потом - клиент. Когда будешь запускать клиента - поток остановится - конструктор выполняется и при первом создании (на сервере) и при втором (на клиенте). Как объяснить? 


конструктора класса RemoteMessageObject будет выполнятся столько, раз сколько создается объект класса,
а конструктор MyRemoteClass должен запускаться только один раз, при первом создании объекта класса RemoteMessageObject,
т.к. remObject - статик поле этого класса
Код

private static MyRemoteClass remObject = new MyRemoteClass();

собственно у меня так все и работало
в твоем примере MyRemoteClass вызывается при каждом создании RemoteMessageObject

Цитата

а ты уверен, что все книжки по ремоутингу прочитал?  smile А статьи, блоги? Если есть ссылки, кинь, плиз. Почитаю

уверен что не все  smile 
книжки которые читал
ты тоже кинь ссылками если есть ч-ть интересное
PM MAIL   Вверх
tol05
Дата 18.5.2007, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 6
Всего: 170



Ты не следишь за собственными высказываниями smile
ты написал:
Цитата(Grambler @  18.5.2007,  09:30 Найти цитируемый пост)
если же использовать прием из книжки
RemotingConfiguration.RegisterActivatedClientType(typeof(SimpleRemotingAsm.RemoteMessageObject),
                "tcp://localhost:8008");
            RemoteMessageObject simple = new RemoteMessageObject(); 
то все нормально, конструктор выполняется только при первом сооздании объекта, при запуске сервера

Какой конструктор? Мне показалось, ты имел в виду RemoteMessageObject()
я ответил:
Цитата(tol05 @  18.5.2007,  11:39 Найти цитируемый пост)
поставь в строчке "Count++;" конструктора класса RemoteMessageObject брейкпоинт ....

а теперь ты мне:
Цитата(Grambler @  18.5.2007,  14:37 Найти цитируемый пост)
конструктора класса RemoteMessageObject будет выполнятся столько, раз сколько создается объект класса

Извини, по-моему мы просто оба устали smile
что такое 
Цитата(Grambler @  18.5.2007,  14:37 Найти цитируемый пост)
статик поле 

я догадывался и раньше  smile а вот почему это статик поле два раза инициализируется - я попытался объяснить так, как понял сам (или внушил себе, что понял). 
Да, два раза, но не в одном процессе, иначе бы валился бы MyRemoteClass не в конструкторе, а гораздо раньше, до конструктора и не дошел бы. Валится из-за того, что статический член класса RemoteMessageObject, создаваемого в процессе клиента (но только временно, до вызова прокси) пытается повеситься на порт, где висит статический член класса RemoteMessageObject, создаваемого в процессе сервера. 

Пока больше ничем помочь не смогу. Но мои объяснения про Activator мне и самому, если честно, не очень нравятся. Я еще наведу справки, если что-то прояснится, сообщу.

полезная книжка по ремоутингу Маклин С., Нафтел Дж,, Уильяме К.  "Microsoft .NET Remoting"
http://www.zipsites.ru/books/maklin_microsoft_net_remoting/
старовата, но по второму фреймворку ничего вроде не выходило. Да и изменения незначительны


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
Grambler
Дата 18.5.2007, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 22.12.2006

Репутация: нет
Всего: нет



Цитата(tol05 @  18.5.2007,  15:06 Найти цитируемый пост)
Ты не следишь за собственными высказываниями ты написал:Цитата(Grambler @  18.5.2007,  09:30 )если же использовать прием из книжкиRemotingConfiguration.RegisterActivatedClientType(typeof(SimpleRemotingAsm.RemoteMessageObject),                "tcp://localhost:8008");            RemoteMessageObject simple = new RemoteMessageObject(); то все нормально, конструктор выполняется только при первом сооздании объекта, при запуске сервераКакой конструктор? Мне показалось, ты имел в виду RemoteMessageObject()


нет, я имел ввиду что в твоем примере конструктор MyRemoteClass() выполнялся при создании,
 как на серверк, так и на клиенте
а в моем только 1 раз на сервере, на клиенте уже нет, поэтому и ошибки с сокетом не было 

Цитата

Извини, по-моему мы просто оба устали 
что такое Цитата(Grambler @  18.5.2007,  14:37 )
статик поле 


не понял в чем вопрос,
но вот оно 
private static MyRemoteClass remObject = new MyRemoteClass();

извиняюсь, за недостаточно корректные фразы и туманные объясения  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
cully
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, cully, mr.DUDA, Exception.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Распределённые приложения и сеть | Следующая тема »


 




[ Время генерации скрипта: 0.0919 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.