На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Про ремоутинг , ну где же вы спецы
    Здрасте, сначала старая проблема с приведением интерфейса, порылся как посоветовали, нашел 2 атрибута, но так ничё умного и не смог с ними сотворить :huh:

    Несколько новых вопросов:

    1) Можно ли на сервере так публиковать исключение, что бы его был обязан обработать клиент?

    2) Как можно "прихлопнуть" клиента, т.е. закрыть все объекты что он открыл по ссылке? Я так понимаю это как то связанно с временем жизни объекта класса MarshalByRefObject?

    3) Как узнать удалённый ип в сессии с клиентом?
      Цитата TerraGhost @
      1) Можно ли на сервере так публиковать исключение, что бы его был обязан обработать клиент?

      Шарп не джава, заставить когото обрабатывать исключения нельзя.
      Цитата TerraGhost @
      2) Как можно "прихлопнуть" клиента, т.е. закрыть все объекты что он открыл по ссылке? Я так понимаю это как то связанно с временем жизни объекта класса MarshalByRefObject?


      Раз ты используешь MarshalByRefObject следовательно не совсем то и ссылку на объект ты получаешь. Реально ты работаешь через прокси Transparent Proxy, читай соответсвующую литературу. Что касается времени жизни объекта, то ты не переживай. В зависимости от того, в каком режиме ты запустил сервер. Объекты живут либо время обработки запроса и на каждый из них реагирует собственный инстанс сервера(SingleCall) либо все запросы обслуживает один инстанс (Singleton, правда что бы он не пересоздавался нужно переопределить метод InitializeLifetimeService)


      ExpandedWrap disabled
            public class RemoteObject: MarshalByRefObject
            {
                //если этого не сделать то через пять минут простоя в режиме Singleton, будет создан новый инстанс класса RemoteObject
                public override object InitializeLifetimeService()
                {
                    return null;
                }
            }

      Цитата TerraGhost @
      Как узнать удалённый ип в сессии с клиентом?

      Веди на сервере список клиентов. P.S. Скорее всего тебе прийдется разобраться как работать с приемниками (Sink). До IP адреса легко добраться именно там получив доступ к заголовкам транспортного протокола
      ExpandedWrap disabled
        IPAddress clientAddress = requestHeaders[CommonTransportKeys.IPAddress] as IPAddress;


      в этом коде requestHeaders это переменная которая реализует интерфейс ITransportHeaders доступная в стандартном для приемников методе обработки сообщений ProcessMessage (серверные приемники обязаны реализовывать интерфейсс IServerChannelSink, вот он то и требует реализовывать этот метод)

      Добавлено
      ExpandedWrap disabled
        using System;
        using System.Collections;
        using System.IO;
        using System.Net;
        using System.Runtime.Remoting.Channels;
        using System.Runtime.Remoting.Messaging;
         
        namespace ClassLibRemotingIPSink
        {
            public class ClientIPServerSinkProvider : IServerChannelSinkProvider
            {
                private IServerChannelSinkProvider next = null;
         
                public ClientIPServerSinkProvider(IDictionary properties, ICollection providerData)
                {
         
                }
         
                public void GetChannelData(IChannelDataStore channelData)
                {
         
                }
         
                public IServerChannelSink CreateSink(IChannelReceiver channel)
                {
         
                    IServerChannelSink nextSink = null;
         
                    if (next != null)
                    {
                        nextSink = next.CreateSink(channel);
                    }
         
                    return new ClientIPServerSink(nextSink);
                }
         
                public IServerChannelSinkProvider Next
                {
                    get { return next; }
                    set { next = value; }
                }
            }
         
            public class ClientIPServerSink : BaseChannelObjectWithProperties, IServerChannelSink, IChannelSinkBase
            {
                private IServerChannelSink _next;
         
                public ClientIPServerSink(IServerChannelSink next)
                {
                    _next = next;
                }
         
                public void AsyncProcessResponse(System.Runtime.Remoting.Channels.IServerResponseChannelSinkStack sinkStack, System.Object state, System.Runtime.Remoting.Messaging.IMessage msg, System.Runtime.Remoting.Channels.ITransportHeaders headers, System.IO.Stream stream)
                {
         
                }
         
                public Stream GetResponseStream(System.Runtime.Remoting.Channels.IServerResponseChannelSinkStack sinkStack, System.Object state, System.Runtime.Remoting.Messaging.IMessage msg, System.Runtime.Remoting.Channels.ITransportHeaders headers)
                {
                    return null;
                }
         
                public System.Runtime.Remoting.Channels.ServerProcessing ProcessMessage(System.Runtime.Remoting.Channels.IServerChannelSinkStack sinkStack, System.Runtime.Remoting.Messaging.IMessage requestMsg, System.Runtime.Remoting.Channels.ITransportHeaders requestHeaders, System.IO.Stream requestStream, out System.Runtime.Remoting.Messaging.IMessage responseMsg, out System.Runtime.Remoting.Channels.ITransportHeaders responseHeaders, out System.IO.Stream responseStream)
                {
                    if (_next != null)
                    {
                        IPAddress ip = requestHeaders[CommonTransportKeys.IPAddress] as IPAddress;
                        if (ip != null)
                        {
                            Console.WriteLine(ip.ToString());
                            CallContext.SetData("ClientIPAddress", ip);
                        }
                        ServerProcessing spres = _next.ProcessMessage(sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);
                        return spres;
                    }
                    else
                    {
                        responseMsg = null;
                        responseHeaders = null;
                        responseStream = null;
                        return new ServerProcessing();
                    }
                }
         
                public IServerChannelSink NextChannelSink
                {
                    get { return _next; }
                    set { _next = value; }
                }
            }
         
        }


      Код реализует серверный приемник где происходит извлечение IP клиента из заголовка транспортного протокола. Затем айпишник помещается в контекст вызова. Это позволит тебе потом легко к нему добраться из кода сервера, или же можешь производить с ними всю работу прям в приемнике. Подключаются приемники в инфраструктуру Remoting через конфигурационные файлы.

      <system.runtime.remoting>
      <application>
      ............................................

      <channels>
      <channel ref="http" port="8124">
      <serverProviders>
      <provider
      type="ClassLibRemotingIPSink.ClientIPServerSinkProvider, ИмяСборки" />
      <formatter ref="binary" />
      </serverProviders>
      </channel>
      </channels>

      </application>
      </system.runtime.remoting>

      Думаю проблем у тебя быть не должно. Но почитать о приемниках всеравно настоятельно рекомендую.
      Сообщение отредактировано: juice -
        1)

        Цитата

        Шарп не джава, заставить когото обрабатывать исключения нельзя.


        Я не совсем ясно выразился, мне нужно сделать так, что бы исключение вызвалось на клиентской стороне, так как придумывать енумы с кодами возврата функции немного гиморно. Это можно или нет?

        2)Опять не туда. Мне нужно сотворить блокировку всех вызовов от удалённого объекта на сервере. Это можно сделать с помощью проверок в начале каждой функции, что такой-то клиент, умеет право вызывать эту функцию, либо, как-то прикрыть сетевое соединение сразу.

        3) спс, погляжу

        Ничё там с приведение интерфесов никак? меня это просто убивает :wall:
        Сообщение отредактировано: TerraGhost -
          Цитата TerraGhost @
          Я не совсем ясно выразился, мне нужно сделать так, что бы исключение вызвалось на клиентской стороне, так как придумывать енумы с кодами возврата функции немного гиморно. Это можно или нет?

          Почему нет? У нас с этим проблем никогда не было. Все исключения объявляешь в отельной сборке, цепляешь ее и к серверу и к клиенту. Пробрасываешь на сервере обрабатываешь уже на клиенте.
          Цитата TerraGhost @
          Опять не туда. Мне нужно сотворить блокировку всех вызовов от удалённого объекта на сервере. Это можно сделать с помощью проверок в начале каждой функции, что такой-то клиент, умеет право вызывать эту функцию, либо, как-то прикрыть сетевое соединение сразу.

          Ну надо не методы прятать от клиента, а реализовать ему авторизацию на доступ к соответствующим методам. Читай в инете много инфы про авторизацию и про аутентификацию в ремотинге. Для декларативной модели в общем случае проведя аутентификацию ты получишь роли клиента, а методы метяться атрибутами по принципу эти роли имеют доступ, а эти нет к этому методу. В императивной модели сможешь проверять кодом не используя атрибуты. Вобщем читай.
            Цитата

            Почему нет? У нас с этим проблем никогда не было. Все исключения объявляешь в отельной сборке, цепляешь ее и к серверу и к клиенту. Пробрасываешь на сервере обрабатываешь уже на клиенте.


            Что я не так делаю?

            Общая бибилиотека

            ExpandedWrap disabled
                  public interface IServer
                  {
                      void ExceptionFunction ();
                  }
               
                  public class MyException : Exception
                  {
               
                  }


            Сервер

            ExpandedWrap disabled
                  internal static class Program
                  {
                      internal static void Main ()
                      {
                          Server.Start ();
               
                          Console.ReadKey ();
                      }
                  }    
               
                  public class Server : MarshalByRefObject, IServer
                  {
                      public static void Start ()
                      {
                          BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider ();
                          provider.TypeFilterLevel = TypeFilterLevel.Full;
                          IDictionary props = new Hashtable ();
                          props["port"] = 12345;
                          TcpChannel channel = new TcpChannel (props, null, provider);
                          ChannelServices.RegisterChannel (channel, false);
                          RemotingConfiguration.RegisterWellKnownServiceType (typeof (Server), "Server", WellKnownObjectMode.Singleton);
                      }
               
                      public void ExceptionFunction ()
                      {
                          throw new MyException ();
                      }
                  }


            Клиент

            ExpandedWrap disabled
                  internal static class Program
                  {
                      internal static void Main ()
                      {
                          BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider ();
                          provider.TypeFilterLevel = TypeFilterLevel.Full;
                          IDictionary props = new Hashtable ();
                          props["port"] = 0;
                          TcpChannel channel = new TcpChannel (props, new BinaryClientFormatterSinkProvider (), provider);
                          ChannelServices.RegisterChannel (channel, false);
               
                          IServer server = (IServer)Activator.GetObject (typeof (IServer), "tcp://localhost:12345/Server");
                          
                          try
                          {
                              server.ExceptionFunction ();
                          }
                          catch (MyException)
                          {
                              Console.WriteLine ("Ошибка перехвачена");
                          }
               
                          Console.ReadKey ();
                      }
                  }


            И как это исключение "пробросить" на клиент?

            Цитата

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


            Т.е. и поя предыдущая проблема с привредением интерфеса к Disposabe решается, решается назначением функции Dispose на сервере с максимальным уровнем доступа?
              Цитата TerraGhost @
              И как это исключение "пробросить" на клиент?

              Для начала пометь MyException атрибутом [Serializable] А там уже посмотрим пробрасывается или нет. Вообще все собственные типы, что ты собираешься передавать нужно им отмечать. Или же реализовывать сериализацию, через ISerializable.

              Вот те рабочая рыба:

              ExpandedWrap disabled
                using System;
                using System.Security.Permissions;
                using System.Runtime.Remoting;
                using System.Runtime.Serialization;
                 
                namespace Exception.CustomRemotingException
                {
                    [Serializable]
                    public class CustomRemotingException : RemotingException, ISerializable
                    {
                        public CustomRemotingException ()
                        {
                        }
                        
                        public CustomRemotingException (string message) :
                            base(message)
                        {
                        }
                 
                        public CustomRemotingException (string message, System.Exception innerException) :
                            base(message, innerException)
                        {
                        }
                 
                        protected CustomRemotingException (SerializationInfo info, StreamingContext context) :
                            base(info, context)
                        {
                        }
                 
                        public override void GetObjectData(SerializationInfo info, StreamingContext context)
                        {
                            base.GetObjectData(info, context);
                        }
                    }
                }


              Цитата TerraGhost @
              Т.е. и поя предыдущая проблема с привредением интерфеса к Disposabe решается, решается назначением функции Dispose на сервере с максимальным уровнем доступа?

              Вероятно да. Но вообще я не вижу смысла реализовывать IDisposible для Server, обоснуй зачем это может понадобиться. Чисть не управляемые ресурсы или же если хош все руками, то объекты которые создаешь и юзаешь в Server , а самому Server зачем это?
              Сообщение отредактировано: juice -
                Цитата

                Вот те рабочая рыба:


                Сереализовал класс - толку 0, подставил уже сереализованный базовый Exception - толку 0, как бы не извращался, исключение всё равно выбрасывается на сервере.

                Цитата

                Вероятно да. Но вообще я не вижу смысла реализовывать IDisposible для Server, обоснуй зачем это может понадобиться. Чисть не управляемые ресурсы или же если хош все руками, то объекты которые создаешь и юзаешь в Server , а самому Server зачем это?


                Это называется программная логика, у меня в программе все клиенты тоже умеют друг на друга ограниченную видимость в режиме чтения (посредством интерфейсов нижнего уровня), если они будут друг друга приводить к высшим уровням доступа посредством интерфейсов будет чёрт знает что. Вот мне зачем это.
                  TerraGhost, есть еще один тооненький нюанс для проброса исключений с сервера к клиенту :
                  в конфиг нужно добавить:
                  ExpandedWrap disabled
                    <system.runtime.remoting>
                        <customErrors mode="off"/>


                  Добавлено
                  Это добавляется в App.config твоего приложения сервера ремотинг, кроме того, как было сказанно:
                  1. Исключение должно уметь сериализоваться (если оно твое), стандартные уже умеют, их учить не нужно
                  2. Клиент ремотинг должен знать о типе исключения, которое прилетит, иначе он не сможет его десериализовать.
                  Спсб за внимание :)
                    Цитата PIL @
                    в конфиг нужно добавить:

                    <system.runtime.remoting>
                    <customErrors mode="off"/>



                    Hi, PIL именно:)
                      Помогло, всем спасибо.
                        Кстати убиваеца сцылка на объект методом RemotingServices.Disconnect
                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                        0 пользователей:


                        Рейтинг@Mail.ru
                        [ Script execution time: 0,0401 ]   [ 17 queries used ]   [ Generated: 24.04.24, 18:07 GMT ]