Re: .Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой вело
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 06.03.17 07:21
Оценка: 17 (2)
Написал статью .Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой велосипед

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

Само решение очень близко с COM out process взаимодействием на IDispatch.
Помню с удовольствием разбирался с внутренностями TSocketConnection.

Но, в отличие от Idispatch, используется перегрузка методов и операторов, вызов Generic методов с выводом типов или с заданием Generic аргументов.
Поддержка методов расширений для классов, находящихся в одной сборке и для Linq методов.

Также поддержка асинхронных методов и подписка на события, ref и out параметры, доступ по индексу [], поддержка итераторов в foreach.

В отличии от Web Api, не нужно писать специально серверный код Controller, Hub ы.
Это близко к AppDomain c Remouting но, в отличие от Remoting, каждый класс является аналогом MarshalByRefObject. То есть, мы можем создать любой объект на стороне сервера и вернуть ссылку на него (некоторые языки из чисел поддерживают только double).
При вызове методов, напрямую сериализуются параметры только следующих типов: числа, строки, дата, Guid и byte[]. Для остальных типов нужно их создать на стороне сервера, а в параметрах методов уже передаются ссылки на них.

и солнце б утром не вставало, когда бы не было меня
Re[7]: .Net Core, AppDomain, RPC свой велосипед
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.02.17 12:57
Оценка: 16 (1)
Здравствуйте, Serginio1, Вы писали:

S>Ghb добавлении

S>using System?.IO?.Pipes
S> ругается на Pipes

Assembly
System.IO.Pipes.dll

... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[4]: .Net Core, AppDomain, RPC свой велосипед
От: Tom Россия http://www.RSDN.ru
Дата: 21.02.17 10:57
Оценка: +1
S> А в чем треш? То есть RPC(Remoting),WCF это не треш?
Трэш

S>Тот же COM out server тоже треш?

Это не трэш, это разложившийся труп

S> И кстати сколько выдает веб апи вызовов в секунду?

Посчитайте, возтмите тот же пример веб сервера на Pipelines и замеряйте.

S> Еще раз это замена AppDomain и Remotig. Они то надеюсь не треш?

Какая нафиг замена, очнитесь О чём вы вообще.
AppDomain предназначены для изоляции кода и возможности по разному настраивать безопастность, для того что бы иметь возможность выгружать сборку, IPC и ремоутинг тут только для обеспечения этих возможностей. Какой смысл в вашем IPC без реальных фич App Domain
Народная мудрось
всем все никому ничего(с).
Re: .Net Core, AppDomain, RPC свой велосипед
От: hardcase Пират http://nemerle.org
Дата: 28.02.17 10:19
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

S>Кто о чем, а вшивый о бане.


S> Сейчас в .Net Core нет AppDomain и RPC .


Я бы использовал Protobuf + как там принято в .NET Core сообщения передавать между процессами. Никакой рефлексии, магии аля MarshalByRefObject и граблей с маршаллингом того, что не предназначено для маршаллинга.
/* иЗвиНите зА неРовнЫй поЧерК */
.Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой вело
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 19.02.17 14:30
Оценка:
Написал статью .Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой велосипед

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

Само решение очень близко с COM out process взаимодействием на IDispatch.
Помню с удовольствием разбирался с внутренностями TSocketConnection.

Но, в отличие от Idispatch, используется перегрузка методов и операторов, вызов Generic методов с выводом типов или с заданием Generic аргументов.
Поддержка методов расширений для классов, находящихся в одной сборке и для Linq методов.

Также поддержка асинхронных методов и подписка на события, ref и out параметры, доступ по индексу [], поддержка итераторов в foreach.

В отличии от Web Api, не нужно писать специально серверный код Controller, Hub ы.
Это близко к AppDomain c Remouting но, в отличие от Remoting, каждый класс является аналогом MarshalByRefObject. То есть, мы можем создать любой объект на стороне сервера и вернуть ссылку на него (некоторые языки из чисел поддерживают только double).
При вызове методов, напрямую сериализуются параметры только следующих типов: числа, строки, дата, Guid и byte[]. Для остальных типов нужно их создать на стороне сервера, а в параметрах методов уже передаются ссылки на них.

и солнце б утром не вставало, когда бы не было меня
Отредактировано 06.03.2017 7:20 Serginio1 . Предыдущая версия . Еще …
Отредактировано 03.03.2017 17:28 Serginio1 . Предыдущая версия .
Отредактировано 20.02.2017 7:19 Serginio1 . Предыдущая версия .
Re: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 20.02.17 13:19
Оценка:
Здравствуйте, Serginio1, Вы писали:

Вобщем сделал на Tcp/IP

Но скорость вызова чуть больше 2000 вызовов в секунду. Даже не знаю это много или мало?


Вот клиент
  public class AutoWrapClient : DynamicObject
    {
       public int Target;
        IPEndPoint IpEndpoint;

        public AutoWrapClient(int Target,IPEndPoint IpEndpoint)
        {
            //  IPEndPoint ipEndpoint = new IPEndPoint(IPAddress.Parse(АдресСервера), порт);
            this.Target = Target;
            this.IpEndpoint = IpEndpoint;


        }
        // вызов метода

        static public string LastError;

       public static dynamic GetProxy(string ServerAddres, int port)
        {

              IPEndPoint ipEndpoint = new IPEndPoint(IPAddress.Parse(ServerAddres), port);
            return new AutoWrapClient(0, ipEndpoint);

        }
        private BinaryReader SendMessage(MemoryStream stream)
        {

            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            { client.Connect(IpEndpoint);
                using (var ns = new NetworkStream(client))
                {
                    stream.Position = 0;
                    ns.Write(BitConverter.GetBytes((Int32)stream.Length), 0, 4);
                    stream.CopyTo(ns);

                    using (var br = new BinaryReader(ns))
                    {
                        var streamSize = br.ReadInt32();

                        var res = br.ReadBytes(streamSize);

                        var ms = new MemoryStream(res);
                        ms.Position = 0;
                        return new BinaryReader(ms);
                    }

            }
            }
        }

        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            result = null;

            var ms = new MemoryStream();
            var bw = new BinaryWriter(ms);

            bw.Write((byte)CallMethod.CallFunc);
            bw.Write(Target);
            bw.Write(binder.Name);
            bw.Write(args.Length);

            foreach (var arg in args)
                WorkVariants.WriteObject(arg, bw);

            bw.Flush();

          var res= SendMessage(ms);

            var resRun = res.ReadBoolean();
            var returnValue = WorkVariants.GetObject(res, IpEndpoint);
            if (!resRun)
            {
                if (returnValue != null && returnValue.GetType() == typeof(string))
                    LastError = (string)returnValue;


                return false;
            }

            result = returnValue;
            //  Error=AutoWrap.СообщитьОбОшибке("не найден дженерик тип "+ИмяМетода);
            return true;


        }
    }



И вызов

 Console.OutputEncoding = System.Text.Encoding.UTF8;

        //Process.Start
        Console.WriteLine("Hello Client!");

        var wrap = Client.AutoWrapClient.GetProxy("127.0.0.1", 6891);

        int res = wrap.ReturnParam(3);
        Console.WriteLine(res);

        string str = wrap.ReturnParam("Hello"); // Возвращает параметр 
        Console.WriteLine(str);
        Console.WriteLine(wrap.ReturnParam(3.14));
        Console.WriteLine(wrap.ReturnParam(DateTime.Now));

        decimal dc = 678.89M;
        Console.WriteLine(dc);
        var stopWatch = new System.Diagnostics.Stopwatch();
        int count = 0;
        stopWatch.Start();
        for (int i = 0; i < 10000; i++)
        {
            count += wrap.ReturnParam(i);

        }

        stopWatch.Stop();
        var ts = stopWatch.Elapsed;
        var elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds,
   ts.Milliseconds / 10, 0);

        Console.WriteLine(count);
        Console.WriteLine(elapsedTime);
        Console.ReadLine();
и солнце б утром не вставало, когда бы не было меня
Отредактировано 21.02.2017 7:11 Serginio1 . Предыдущая версия .
Re: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.02.17 09:01
Оценка:
Здравствуйте, Serginio1, Вы писали:

Ну судя по огромному количеству отзывов это осбо не нужно.

Пока реализовал такие вызовы

var wrap = Client.AutoWrapClient.GetProxy("127.0.0.1", 6891);

//ReturnParam просто возвращает переданный параметр
// Через него проверим отправку и возврат результата

        int res = wrap.ReturnParam(3);
        Console.WriteLine(res);

        string str = wrap.ReturnParam("Привет");
        Console.WriteLine(str);
        Console.WriteLine(wrap.ReturnParam(3.14));
        Console.WriteLine(wrap.ReturnParam(DateTime.Now));

        decimal dc = 678.89M;
        Console.WriteLine(dc);

        var ba = new byte[10];
        for (int i = 0; i < ba.Length; i++)
        {
            ba[i]=(byte)i;

        }

        byte[] baRes = wrap.ReturnParam(ba);
        for (int i = 0; i < ba.Length; i++)
        {
            Console.Write(i+",");

        }

        Console.WriteLine("");

      

// Загрузим стороннюю сборку и получим из неё тип
// Сборка должна быть в директории сервера

        var Тестовый = wrap.Тип("TestDllForCoreClr.Тестовый", "TestDll");
// На основании типа создадим объект
        var TO = wrap.New(Тестовый,"Свойство из Конструктора");

// Получим свойство объекта
        Console.WriteLine("Свойство Объекта " + TO.СвойствоОбъекта);

        var EO = TO.ПолучитьExpandoObject();
        Console.WriteLine("Свойство ExpandoObject Имя "+EO.Имя);
        Console.WriteLine("Свойство ExpandoObject Число "+EO.Число);

           int rs = TO.ПолучитьЧисло(89);
        count = 0;
        stopWatch.Restart();
        for (int i = 0; i < 1000; i++)
        {
            count += TO.ПолучитьЧисло(i);

        }

        stopWatch.Stop();



То есть получаем реальный RPC/
Пока сериализуются напрямую

public class WorkVariants
    {
        internal static Dictionary<Type, EnumVar> СоответствиеТипов;
        
        static WorkVariants()
        {

            СоответствиеТипов = new Dictionary<Type, EnumVar>()
            { 
                { typeof(Int16),EnumVar.VTYPE_I2 },
                {typeof(Int32),EnumVar.VTYPE_I4 },
                {typeof(float),EnumVar.VTYPE_R4 },
                {typeof(double),EnumVar.VTYPE_R8 },
                {typeof(bool),EnumVar.VTYPE_BOOL },
                {typeof(sbyte),EnumVar.VTYPE_I1 },
                {typeof(byte),EnumVar.VTYPE_UI1 },
                {typeof(UInt16),EnumVar.VTYPE_UI2},
                {typeof(UInt32),EnumVar.VTYPE_UI4},
                {typeof(Int64),EnumVar.VTYPE_I8},
                {typeof(UInt64),EnumVar.VTYPE_UI8},
                {typeof(string),EnumVar.VTYPE_PWSTR},
                {typeof(byte[]),EnumVar.VTYPE_BLOB},
                {typeof(DateTime),EnumVar.VTYPE_DATE},
                {typeof(AutoWrapClient),EnumVar.VTYPE_AutoWrap}//,
             //   {typeof(AutoWrap),EnumVar.VTYPE_JSObject}
            };


        }

     public static DateTime ReadDateTime(BinaryReader stream)
        {
            long nVal = stream.ReadInt64();
            //get 64bit binary
            return DateTime.FromBinary(nVal);


        }

        public static void WriteDateTime(DateTime value,BinaryWriter stream)
        {
            long nVal = value.ToBinary();
            //get 64bit binary
             stream.Write(nVal);


        }
        public static byte[] ReadByteArray(BinaryReader stream)
        {
            var length = stream.ReadInt32();
            return stream.ReadBytes(length);

        }
      public static  object GetObject(BinaryReader stream, IPEndPoint IpEndpoint)
        {
            
            EnumVar тип =(EnumVar)stream.ReadByte();

            switch (тип)
            {
                case EnumVar.VTYPE_EMPTY:
                case EnumVar.VTYPE_NULL: return null;
                case EnumVar.VTYPE_I2: return stream.ReadInt16();
                case EnumVar.VTYPE_I4: return stream.ReadInt32();
                case EnumVar.VTYPE_R4: return stream.ReadSingle();
                case EnumVar.VTYPE_R8: return stream.ReadDouble();
                case EnumVar.VTYPE_BOOL:return stream.ReadBoolean();
                case EnumVar.VTYPE_I1: return stream.ReadSByte();
                case EnumVar.VTYPE_UI1: return stream.ReadByte();
                case EnumVar.VTYPE_UI2: return stream.ReadUInt16();

                case EnumVar.VTYPE_UI4: return stream.ReadUInt32();

                case EnumVar.VTYPE_I8: return stream.ReadInt64();
                case EnumVar.VTYPE_UI8: return stream.ReadUInt64();
                case EnumVar.VTYPE_PWSTR:

                    var str= stream.ReadString();

                    return str;

                case EnumVar.VTYPE_BLOB:
                                      
                    return ReadByteArray(stream);
                case EnumVar.VTYPE_DATE:
                   
                    return ReadDateTime(stream);

                case EnumVar.VTYPE_AutoWrap:
                        var Target= stream.ReadInt32();
                        var AW = new AutoWrapClient(Target, IpEndpoint);


                    return AW;
            }
            return null;
            }


    
        public static bool WriteObject(object Объект, BinaryWriter stream)
        {

            

            if (Объект == null)
            {

                stream.Write((Int16)EnumVar.VTYPE_NULL);
                stream.Write((Int32)0);
                return true;

            }


            EnumVar type;

            var res = СоответствиеТипов.TryGetValue(Объект.GetType(), out type);

            if (!res) return false;


            stream.Write((byte)type);
            switch (type)
            {
                case EnumVar.VTYPE_I2:  stream.Write((Int16) Объект); break;
                case EnumVar.VTYPE_I4: stream.Write((Int32)Объект); break;
                case EnumVar.VTYPE_R4: stream.Write((float)Объект); break;
                case EnumVar.VTYPE_R8: stream.Write((double)Объект); break;
                case EnumVar.VTYPE_BOOL: stream.Write((bool)Объект); break;
                case EnumVar.VTYPE_I1:  stream.Write((sbyte)Объект); break;
                case EnumVar.VTYPE_UI1: stream.Write((byte)Объект); break;
                case EnumVar.VTYPE_UI2: stream.Write((UInt16)Объект); break;

                case EnumVar.VTYPE_UI4: stream.Write((UInt32)Объект); break;

                case EnumVar.VTYPE_I8: stream.Write((Int64)Объект); break;
                case EnumVar.VTYPE_UI8: stream.Write((UInt64)Объект); break;
                case EnumVar.VTYPE_PWSTR: stream.Write((string)Объект); break;

                case EnumVar.VTYPE_BLOB: stream.Write((byte[])Объект); break;
                case EnumVar.VTYPE_DATE: WriteDateTime((DateTime)Объект, stream);  break;
                case EnumVar.VTYPE_AutoWrap:
                    // УстановитьСтрокуВIntPtr(((AutoWrap)Объект).ПолучитьСсылку(), Элемент);
                    // Marshal.WriteInt16(текПоз, (Int16)EnumVar.VTYPE_PWSTR);
                    stream.Write(((AutoWrapClient)Объект).Target);
                    break;
                    
            }
            return true;
        }

    }


Для ускорения можно вручную сериализовать и десериализовать в byte[]

Буду рад любым идеям и критике
и солнце б утром не вставало, когда бы не было меня
Re[2]: .Net Core, AppDomain, RPC свой велосипед
От: Tom Россия http://www.RSDN.ru
Дата: 21.02.17 10:22
Оценка:
S>Но скорость вызова чуть больше 2000 вызовов в секунду. Даже не знаю это много или мало?
Это настолько неприлично мало что не стоило писать вообще.
Народная мудрось
всем все никому ничего(с).
Re[2]: .Net Core, AppDomain, RPC свой велосипед
От: Tom Россия http://www.RSDN.ru
Дата: 21.02.17 10:23
Оценка:
S>Ну судя по огромному количеству отзывов это осбо не нужно.
Сорри но это жесточайший треш, чем вам веб апи не подошёл?
Народная мудрось
всем все никому ничего(с).
Re[3]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.02.17 10:34
Оценка:
Здравствуйте, Tom, Вы писали:

S>>Но скорость вызова чуть больше 2000 вызовов в секунду. Даже не знаю это много или мало?

Tom>Это настолько неприлично мало что не стоило писать вообще.

А можно поподробнее. Рядом пишут http://rsdn.org/forum/network/6704452.1
Автор: Mr.Delphist
Дата: 21.02.17

2000 вызовов в секунду это 2 вызова каждую миллисекунду, т.е. каждый вызов по 500 микросекунд. Почему Вы считаете, что в диалоговом режиме (вопрос-ответ) TCP/IP должен дать больше? Ведь латентность ОС на процесс и так измеряется в десятках миллисекунд.

и солнце б утром не вставало, когда бы не было меня
Re[3]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.02.17 10:36
Оценка:
Здравствуйте, Tom, Вы писали:

S>>Ну судя по огромному количеству отзывов это осбо не нужно.

Tom>Сорри но это жесточайший треш, чем вам веб апи не подошёл?

А в чем треш? То есть RPC(Remoting),WCF это не треш?

Тот же COM out server тоже треш?

И кстати сколько выдает веб апи вызовов в секунду?

Еще раз это замена AppDomain и Remotig. Они то надеюсь не треш?
и солнце б утром не вставало, когда бы не было меня
Отредактировано 21.02.2017 10:39 Serginio1 . Предыдущая версия . Еще …
Отредактировано 21.02.2017 10:38 Serginio1 . Предыдущая версия .
Отредактировано 21.02.2017 10:37 Serginio1 . Предыдущая версия .
Re[5]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.02.17 11:15
Оценка:
Здравствуйте, Tom, Вы писали:

S>> А в чем треш? То есть RPC(Remoting),WCF это не треш?

Tom>Трэш

S>>Тот же COM out server тоже треш?

Tom>Это не трэш, это разложившийся труп

Угу а веб сервера это тот же труп только по другим протоколам.

S>> И кстати сколько выдает веб апи вызовов в секунду?

Tom>Посчитайте, возтмите тот же пример веб сервера на Pipelines и замеряйте.
Ну ты же говоришь, что это медленно, значит у тебя есть замеры?
Ну дык подскажи как для .Net Core Pipelines использовать. Буду благодарен.


S>> Еще раз это замена AppDomain и Remotig. Они то надеюсь не треш?

Tom>Какая нафиг замена, очнитесь О чём вы вообще.
Tom>AppDomain предназначены для изоляции кода и возможности по разному настраивать безопастность, для того что бы иметь возможность выгружать сборку, IPC и ремоутинг тут только для обеспечения этих возможностей. Какой смысл в вашем IPC без реальных фич App Domain

А какие фичи App Domain
Можно запустить процесс, передать в параметрах номер порта, настроить безопасность. В чем отличие?
и солнце б утром не вставало, когда бы не было меня
Re[5]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.02.17 11:18
Оценка:
Здравствуйте, Tom, Вы писали:

S>> А в чем треш? То есть RPC(Remoting),WCF это не треш?

Tom>Трэш

Ясно и приложения должны обмениваться исключительно через HTTP сервисы и SignalR?
http://rsdn.org/forum/dotnet.web/6704296
Автор: alex1010
Дата: 21.02.17
и солнце б утром не вставало, когда бы не было меня
Re[6]: .Net Core, AppDomain, RPC свой велосипед
От: Tom Россия http://www.RSDN.ru
Дата: 21.02.17 11:30
Оценка:
S>Ясно и приложения должны обмениваться исключительно через HTTP сервисы и SignalR?
Причём тут SignalR вообще

Если вас ваше решение устраивает оно для вас белое пушистое и быстрое то пусть так и будет.
Народная мудрось
всем все никому ничего(с).
Re[7]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.02.17 11:42
Оценка:
Здравствуйте, Tom, Вы писали:

S>>Ясно и приложения должны обмениваться исключительно через HTTP сервисы и SignalR?

Tom>Причём тут SignalR вообще
А как ты события передавать будешь?

Tom>Если вас ваше решение устраивает оно для вас белое пушистое и быстрое то пусть так и будет.

Так я хочу получить советы. Как сделать так, что бы это устраивало не только меня одного.
и солнце б утром не вставало, когда бы не было меня
Re[6]: .Net Core, AppDomain, RPC свой велосипед
От: Tom Россия http://www.RSDN.ru
Дата: 21.02.17 11:43
Оценка:
Tom>>Посчитайте, возтмите тот же пример веб сервера на Pipelines и замеряйте.
S>Ну ты же говоришь, что это медленно, значит у тебя есть замеры?
Посмотри тесты techempower, даже код который в базу лезет работает на 2 порядка быстрее.
Не говоря о plaintext

S> Ну дык подскажи как для .Net Core Pipelines использовать. Буду благодарен.

https://github.com/davidfowl/PipelinesSample

S>Можно запустить процесс, передать в параметрах номер порта, настроить безопасность. В чем отличие?

Во всём, глупая дискуссия.

ЗЫ: В упор не понимаю что и зачем ты делаешь. Сделать быстрый IO framework у тебя не получится, повторить функционал AppDomain тем более, тогда вопрос что вообще ты хочешь добиться.

ЗЫЫЫ: Если надо просто вызывать удалённый процесс — посмотри на grpc
Народная мудрось
всем все никому ничего(с).
Re[7]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.02.17 12:18
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>>>Посчитайте, возтмите тот же пример веб сервера на Pipelines и замеряйте.

S>>Ну ты же говоришь, что это медленно, значит у тебя есть замеры?
Tom>Посмотри тесты techempower, даже код который в базу лезет работает на 2 порядка быстрее.
Tom>Не говоря о plaintext

S>> Ну дык подскажи как для .Net Core Pipelines использовать. Буду благодарен.

Tom>https://github.com/davidfowl/PipelinesSample

Ок посмотрю. Спасибо. Сейчас сделаю на Tcp/Ip потом возьмусь за PipelinesSample


S>>Можно запустить процесс, передать в параметрах номер порта, настроить безопасность. В чем отличие?

Tom>Во всём, глупая дискуссия.

Tom>ЗЫ: В упор не понимаю что и зачем ты делаешь. Сделать быстрый IO framework у тебя не получится, повторить функционал AppDomain тем более, тогда вопрос что вообще ты хочешь добиться.


Ну раз ты говоришь о том что пайпы на два порядка выше, то есть 200к вызовов в секунду, то это оочень быстрый Фреймворк.

Tom>ЗЫЫЫ: Если надо просто вызывать удалённый процесс — посмотри на grpc


Спасибо посмотрю.
и солнце б утром не вставало, когда бы не было меня
Re[8]: .Net Core, AppDomain, RPC свой велосипед
От: Tom Россия http://www.RSDN.ru
Дата: 21.02.17 12:32
Оценка:
S> Ок посмотрю. Спасибо. Сейчас сделаю на Tcp/Ip потом возьмусь за PipelinesSample
Я бы grpc в первую очередь смотрел
Народная мудрось
всем все никому ничего(с).
Re[9]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.02.17 12:53
Оценка:
Здравствуйте, Tom, Вы писали:

S>> Ок посмотрю. Спасибо. Сейчас сделаю на Tcp/Ip потом возьмусь за PipelinesSample

Tom>Я бы grpc в первую очередь смотрел

У меня уже сделан через рефлексию вызов удаленных методов аналогичных C#.
То есть поддержка методов с params, с дефолтными параметрами, вызов дженерик методов итд.
То есть ты работаешь с удаленным объектом как со своим.
То есть, можно вызывать методы асинхронно
 var wrap = Client.AutoWrapClient.GetProxy("127.0.0.1", 6891); // Получили удаленный объект



 static async Task<object> GetAsyncResult(dynamic wrap)
    {

        object resTask = await wrap.async.ЧтотоТам(3);

       
        return resTask;
    }


Можно создавать объекты из сборки в каталоге сервера

var Тестовый = wrap.Тип("TestDllForCoreClr.Тестовый", "TestDll");// TestDll в каталоге сервера
        var TO = wrap.New(Тестовый,"Свойство из Конструктора");
        Console.WriteLine("Свойство Объекта " + TO.СвойствоОбъекта);
        TO.СвойствоОбъекта = "Свойство Новое";
        Console.WriteLine("Свойство Объекта " + TO.СвойствоОбъекта);

        var EO = TO.ПолучитьExpandoObject();
        Console.WriteLine("Свойство ExpandoObject Имя "+EO.Имя);
        Console.WriteLine("Свойство ExpandoObject Число "+EO.Число);


То есть код сервера можно не менять, только подсовывать нужные DLL, и создавать из них нужные объекты или вызывать статические методы.
Подключаться к событиям.
Это очень схоже с AppDamain

Можно подключаться к событиям по аналогии с
CEF, Angular 2 использование событий классов .Net Core

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


У меня уже есть велосипед.
Я просто хочу довести до ума. Может кому и пригодится.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 21.02.2017 13:26 Serginio1 . Предыдущая версия . Еще …
Отредактировано 21.02.2017 13:04 Serginio1 . Предыдущая версия .
Отредактировано 21.02.2017 13:02 Serginio1 . Предыдущая версия .
Re[5]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.02.17 17:00
Оценка:
Здравствуйте, Tom, Вы писали:

S>> А в чем треш? То есть RPC(Remoting),WCF это не треш?

Tom>Трэш

S>>Тот же COM out server тоже треш?

Tom>Это не трэш, это разложившийся труп
Которым пользуется куча 1С и иже с ними.
При этом при переходе на 64 разрядную платформу, люди стали возвращаться обратно, так как in process повально 32 разрядные.
WCF я и сейчас пользуюсь с named pipes binding . Но в .Net Core нет, и при этом мою приблуду проще использовать.
Нужна любая сборка.

S>> И кстати сколько выдает веб апи вызовов в секунду?

Tom>Посчитайте, возтмите тот же пример веб сервера на Pipelines и замеряйте.

Вот появятся named pipes в .Net Core на уровне сокетов обязательно проверю.

S>> Еще раз это замена AppDomain и Remotig. Они то надеюсь не треш?

Tom>Какая нафиг замена, очнитесь О чём вы вообще.
Tom>AppDomain предназначены для изоляции кода и возможности по разному настраивать безопастность, для того что бы иметь возможность выгружать сборку, IPC и ремоутинг тут только для обеспечения этих возможностей. Какой смысл в вашем IPC без реальных фич App Domain

Все фичи App Domain есть. Можно управлять и секьюрностью и выгружать и создавать любой объект и вызывать его.
Какие еще нужны фичи?

Кстати Analog System.Security.Permissions in .NET Core


Code Access Security isn't and won't be available in .Net Core. Since all code is effectively running under full trust, it should be enough to remove those attributes.

If you actually want to restrict some code, the recommandation is:


Use operating system provided security boundaries, such as user accounts for running processes with the least set of privileges.

и солнце б утром не вставало, когда бы не было меня
Отредактировано 21.02.2017 17:09 Serginio1 . Предыдущая версия .
Re: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 22.02.17 16:16
Оценка:
Здравствуйте, Serginio1, Вы писали:
К сожалению C# не поддерживает вызов new для TryCreateInstance DinamicObject

Сейчас объект создается так

 var Тестовый = wrap.Тип("TestDllForCoreClr.Тестовый", "TestDll");
// На основании типа создадим объект
  var TO = wrap.New(Тестовый,"Свойство из Конструктора");


То есть мы не можем вызвать используя DinamicObject и TryCreateInstance

var TO = new Тестовый("Свойство из Конструктора");


Но можно и так

var TO = Тестовый.new("Свойство из Конструктора");


Еще один вариант это использовать

TryInvoke(): вызов объекта в качестве делегата

var TO = Тестовый($$,"Свойство из Конструктора");


где $$ константная строка для сравнения Object.ReferenceEquals
и солнце б утром не вставало, когда бы не было меня
Re: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 09:38
Оценка:
Здравствуйте, Serginio1, Вы писали:

Я прекрасно понимаю, что это никому не нужно. Но нужно доделать.
Сил вложено немало. В итоге получилось поделие даже не хуже WCF.
А по мне даже и лучше. Больше возможностей. И при этом можне не писать серверный код.
Очень близко к AppDomain, только все объекты являются MarshalByRefObject.

Поэтому прошу совета помочь оформить и покритиковать.

Что сейчас есть.
Можно подключиться к существующему серверу или запустить процесс по известному пути

if (LoadLocalServer)
        {
            //   connector = ClientRPC.TCPClientConnector.LoadAndConnectToLocalServer(GetParentDir(dir, 4) + $@"\Server\Server\bin\Release\netcoreapp1.1\Server.dll");
            connector = ClientRPC.TCPClientConnector.LoadAndConnectToLocalServer(GetParentDir(dir, 4) + $@"\Server\Server\bin\Debug\netcoreapp1.1\Server.dll");
        }
        else
        {
            connector = new ClientRPC.TCPClientConnector("127.0.0.1", port);
            // Нужен для асинхронных методов и Событий
            // Если их нет то и смысла слушать порт нет
            port = ClientRPC.TCPClientConnector.GetAvailablePort(6892);
            connector.Open(port, 2);

        }



После подключения можно получить типы и создавать объекты из сборок находящиеся в папке сервера и в паках CoreClr

            CoreClrDir = GetDirName(typeof(string));
            NetObjectToNativeDir = GetDirName(typeof(AutoWrap));



Поддержка статических и объектных методов, Дженерик методов с выводом типа, с дженерик аргуметами, индесаторов, итераторов
Поддержка асинхронных методов и событий. Поддержка ref и out параметров
Например

static async Task<object> GetGenericAsyncResult(dynamic TO)
    {
                 //public async Task<V> GenericMethodAsync<K, V>(K param, string param4 = "Test")
        object resTask = await TO.async.GenericMethodAsync(new object[] { "System.Int32", "System.String" }, 44);
        return resTask;
    }

static void TestGenericMethods(ClientRPC.TCPClientConnector connector)
    {


        Dictionary<int, string> ClientDict = new Dictionary<int, string>()
        {
            [1] = "Один",
            [2] = "Второй2",
            [3] = "Один3"
        };

        var @Dictionary2 = wrap.GetType("System.Collections.Generic.Dictionary`2", "System.Collections");
        var @DictionaryIntString = wrap.GetGenericType(@Dictionary2, "System.Int32", "System.String");

        // Скопируем словарь на сервер
        // Закомментированы различные варианты
        // var dict = connector.CoryTo(@DictionaryIntString, ClientDict);
        // var dict = connector.CoryTo("System.Collections.Generic.Dictionary`2[System.Int32, System.String]", ClientDict);

        // Скопируем словарь на сервер
        var dict = connector.CoryTo(ClientDict);

        Console.WriteLine(wrap.toString(dict));
        Console.WriteLine(dict[2]);

      // Получим тип из сборки TestDll
        var @TestClass = wrap.GetType("TestDllForCoreClr.TestClass", "TestDll");


       // Создадим объект на сервере используя метод _new
        var TO = @TestClass._new("Property  from Constructor");

        // Test асинхронного вызова дженерик метода

        var resGM = GetGenericAsyncResult(TO).Result;
        Console.WriteLine("Вызов дженерик метода с аргументами типов async " + resGM);


        // Вызовем дженерик метод с автовыводом типа
        // public T GenericMethod<V, T>(V param1, T param2, V param3)
        resGM = TO.GenericMethod(dict, 99, "Hello");
        Console.WriteLine("Вызов дженерик метода с выводом типа " + resGM);




        // Test Generic Method с параметрами по умолчанию 
        //public string GenericMethodWithDefaulParam<K, V>(Dictionary<K, V> param1, K param2, int param3 = 4, string param4 = "Test")
        var @Int32 = wrap.GetType("System.Int32");
        resGM = TO.GenericMethodWithDefaulParam(dict, 99);
        Console.WriteLine("Вызов дженерик метода с автовыводом  типов " + resGM);

        resGM = TO.GenericMethodWithDefaulParam(pp(@Int32, "System.String"), dict, 99);
        Console.WriteLine("Вызов дженерик метода с аргументами типов " + resGM);



        // Test Generic Method с параметрами массивом
        // public string GenericMethodWithParams<K, V>(Dictionary<K, V> param1, K param2, params string[] args)

        resGM = TO.GenericMethodWithParams(dict, 99, "First", "Second");
        Console.WriteLine("Вызов дженерик метода с автовыводом  типов " + resGM);

        resGM = TO.GenericMethodWithParams(pp(@Int32, "System.String"), dict, 99, "First", "Second");
        Console.WriteLine("Вызов дженерик метода с аргументами типов " + resGM);


        // public V  GenericMethodWithRefParam<К,V >(К param, V param2, ref string param3)
        var OutParam = new ClientRPC.RefParam("TroLoLo");
        resGM = TO.GenericMethodWithRefParam(5, "GenericMethodWithRefParam", OutParam);
        Console.WriteLine($@"Вызов дженерик метода с автовыводом  типов Ref {resGM}  {OutParam.Value}");
        var GenericArgs = new object[] { "System.String", "System.String" };


        resGM = TO.GenericMethodWithRefParam(GenericArgs, null, "GenericMethodWithRefParam", OutParam);
        Console.WriteLine($@"Вызов дженерик метода с дженерик аргументами Ref {resGM}  {OutParam.Value}");

        // Test return null
        resGM = TO.GenericMethodWithRefParam(GenericArgs, null, null, OutParam);
        Console.WriteLine($@"Вызов дженерик метода с дженерик аргументами Ref {resGM}  {OutParam}");


    }



Напрямую сериализуются byte[],числа, строки,булево,Дата,char,Guid
Для AutoWrapClient передается индекс в хранилище

Но можно скопировать данные на сервер и получить ссылку

var dict = connector.CoryTo(ClientDict);


Внутри используеся Json сериализация

 // Сериализуем объект и отправим представление типа ввиде AssemblyQualifiedName
        public dynamic CoryTo(object obj)
        {
            string type = obj.GetType().AssemblyQualifiedName;
            var str = JsonConvert.SerializeObject(obj);
            return CoryTo(type, str);

        }


При этом мы можем получить и ссылку на byte[], так при обычном методе он сериализуется.

Но для этого нужно загрузить все используемы сборки.

static void TestSerializeObject(ClientRPC.TCPClientConnector connector)
    {
       // Получим на клиенте объект и скопируем его на сервер
        var obj = new TestDllForCoreClr.TestClass("Объект на стороне Клиента");

        dynamic test = null;
        try
        {
            test = connector.CoryTo(obj);

        }
        catch (Exception)
        {

            Console.WriteLine("Ошибка " + connector.LastError);
            var assembly = wrap.GetAssembly("TestDll");
            test = connector.CoryTo(obj);

        }
        Console.WriteLine(test.ObjectProperty);

    }


Поддержка индексаторов и итераторов.


 string[] sa = new string[] { "Нулевой", "Первый", "Второй", "Третий", "Четвертый" };
        var ServerSA = connector.ArrayCoryTo("System.String", sa);
        Console.WriteLine("ServerSA[2]  " + ServerSA[2]);
        ServerSA[2] = "Изменен Параметр по индексу 2";
        Console.WriteLine("ServerSA[2]  " + ServerSA[2]);

        foreach (string value in ServerSA)
            Console.WriteLine("Values  " + value);




 var Dictionary2 = wrap.GetType("System.Collections.Generic.Dictionary`2", "System.Collections");
        var DictionaryIntString = wrap.GetGenericType(Dictionary2, "System.Int32", "System.String");
        //var dict = wrap.New(DictionaryIS);

      
        Dictionary<int, string> ClientDict = new Dictionary<int, string>()
        {
            [1] = "Один",
            [2] = "Второй2",
            [3] = "Один3"
        };

        foreach (string value in ServerSA)
            Console.WriteLine("Values  " + value);


        Console.WriteLine("new  " + DictionaryIntString._new());

        // Можно просто connector.CoryTo(ClientDict);
        // Но бывает что тип только на сервере. На клиенте такого типа нет
        //Но можно использоварть ExpandoObject или JObject
        
        var dict = connector.CoryTo(DictionaryIntString, ClientDict);
        Console.WriteLine("dict[2]  " + dict[2]);
        dict[2] = "Два";
        Console.WriteLine("dict[2]  " + dict[2]);

        // используем класс ClientRPC.RefParam для получения измененного параметра.
        var OutParam = new ClientRPC.RefParam();
        if (dict.TryGetValue(2, OutParam))
        {

            Console.WriteLine("OutParam  " + OutParam.Value);
        }



Вобщем отличие от родного кода это в вызове асинхронного метода за счет добавления слова async

        object resTask = await TO.async.GenericMethodAsync(new object[] { "System.Int32", "System.String" }, 44);


Для вызова дженерик метода с дженерик аргуметами первым параметром должен идти массив типов




// public V  GenericMethodWithRefParam<К,V >(К param, V param2, ref string param3)
        var OutParam = new ClientRPC.RefParam("TroLoLo");
        var GenericArgs = new object[] { "System.String", "System.String" };


        resGM = TO.GenericMethodWithRefParam(GenericArgs, null, "GenericMethodWithRefParam", OutParam);




Ну и подключение к эвентам



 static public void EventWithTwoParameter(dynamic value)
    {
        Console.WriteLine("EventWithTwoParameter" + wrap.toString(value));

        value(ClientRPC.AutoWrapClient.FlagDeleteObject);
    }

    // параметр value:System.String

    static public void EventWithOneParameter(dynamic value)
    {
        Console.WriteLine("EventWithOneParameter " + wrap.toString(value));
    }


    static public void EventWithOutParameter(dynamic value)
    {
        Console.WriteLine("EventWithOutParameter" + wrap.toString(value));
    }

 static void RunTestEvent(ClientRPC.TCPClientConnector connector)
    {
        var EventTest = wrap.GetType("TestDllForCoreClr.EventTest", "TestDll");
        // var test = wrap.New(EventTest);
        var test = EventTest._new();
        var wrapForEvents = connector.CreateWrapperForEvents(test);


        wrapForEvents.AddEventHandler("EventWithTwoParameter", new Action<dynamic>(EventWithTwoParameter));
        wrapForEvents.AddEventHandler("EventWithOneParameter", new Action<dynamic>(EventWithOneParameter));
        wrapForEvents.AddEventHandler("EventWithOutParameter", new Action<dynamic>(EventWithOutParameter));
        test.Run();
    }



Основное отличие от WCF это использование DynamicObjet. Но можно тестировать код напрямую, а затем
приспосабливать его к PPC
и солнце б утром не вставало, когда бы не было меня
Отредактировано 28.02.2017 10:19 Serginio1 . Предыдущая версия . Еще …
Отредактировано 28.02.2017 10:19 Serginio1 . Предыдущая версия .
Отредактировано 28.02.2017 10:17 Serginio1 . Предыдущая версия .
Отредактировано 28.02.2017 10:16 Serginio1 . Предыдущая версия .
Отредактировано 28.02.2017 10:13 Serginio1 . Предыдущая версия .
Отредактировано 28.02.2017 9:53 Serginio1 . Предыдущая версия .
Отредактировано 28.02.2017 9:51 Serginio1 . Предыдущая версия .
Отредактировано 28.02.2017 9:49 Serginio1 . Предыдущая версия .
Отредактировано 28.02.2017 9:47 Serginio1 . Предыдущая версия .
Re[2]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 10:23
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, Serginio1, Вы писали:


S>>Кто о чем, а вшивый о бане.


S>> Сейчас в .Net Core нет AppDomain и RPC .


H>Я бы использовал Protobuf + как там принято в .NET Core сообщения передавать между процессами. Никакой рефлексии, магии аля MarshalByRefObject и граблей с маршаллингом того, что не предназначено для маршаллинга.


А какая огромная разница между Protobuf и Json?
Для JSON есть прекрасная библиотека

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

Да а что тебе не нравится в моей разработке. Почему Protobuf лучше?
Граблей с маршалингом нет, затраты на рефлексию можно не рассматривать при этом все происходит автоматически.

И код мало отличается от работы с объектами напрямую.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 28.02.2017 10:27 Serginio1 . Предыдущая версия .
Re[3]: .Net Core, AppDomain, RPC свой велосипед
От: hardcase Пират http://nemerle.org
Дата: 28.02.17 10:27
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> А какая огромная разница между Protobuf и Json?

S>Для JSON есть прекрасная библиотека

Сообщения протокола известны статически. Непонятно какие типы не уйдут в сеть и не придут внезапно из сети.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: .Net Core, AppDomain, RPC свой велосипед
От: hardcase Пират http://nemerle.org
Дата: 28.02.17 10:29
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Угу а сервер кто писать будет? Вся прелесть в том, что серверную часть тебе даже писать не надо.


Ну вот тут уже надо смотреть что доступно в корке для общения со внешним миром. Написать один раз TCP-сервер и клиент с пулом соединений не очень трудно.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 10:29
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, Serginio1, Вы писали:


S>> А какая огромная разница между Protobuf и Json?

S>>Для JSON есть прекрасная библиотека

H>Сообщения протокола известны статически. Непонятно какие типы не уйдут в сеть и не придут внезапно из сети.


Ну опять же тебе нужно писать сервер. При моем подходе писать сервер не надо. Загружаешь нужные сборки и работаешь с ними удаленного.

Я понимаю, что web Api наше все. А как с асинхронными методами, событиями?
и солнце б утром не вставало, когда бы не было меня
Re[4]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 10:31
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, Serginio1, Вы писали:


S>>Угу а сервер кто писать будет? Вся прелесть в том, что серверную часть тебе даже писать не надо.


H>Ну вот тут уже надо смотреть что доступно в корке для общения со внешним миром. Написать один раз TCP-сервер и клиент с пулом соединений не очень трудно.


Так он написан. Через него и происходит общение.

namespace ClientRPC
{

     public enum EnumVar:byte
    {
        VTYPE_EMPTY = 0,
        VTYPE_NULL,
        VTYPE_I2,                   //int16
        VTYPE_I4,                   //int32
        VTYPE_R4,                   //float
        VTYPE_R8,                   //double
        VTYPE_Decimal,              //Decimal
        VTYPE_DATE,                 //DATE (double)
        VTYPE_BOOL,                 //bool
        VTYPE_I1,                   //int8
        VTYPE_UI1,                  //uint8
        VTYPE_UI2,                  //uint16
        VTYPE_UI4,                  //uint32
        VTYPE_I8,                   //int64
        VTYPE_UI8,                  //uint64
        VTYPE_INT,                  //int   Depends on architecture
        VTYPE_CHAR,                 //char
        VTYPE_PWSTR,                //struct wstr
        VTYPE_BLOB,                 //means in struct str binary data contain
        VTYPE_GUID,                 //Guid
        VTYPE_AutoWrap,             // Net Object
        VTYPE_JSObject



    };


    // Класс WorkVariants осуществляет сериализацию и десериализацию объектов
    public class WorkVariants
    {
        internal static Dictionary<Type, EnumVar> MatchTypes;
        
        static WorkVariants()
        {

            // Напрямую сериализуются byte[],числа, строки,булево,Дата,char,Guid
            //Для AutoWrapClient передается индекс в хранилище
            MatchTypes = new Dictionary<Type, EnumVar>()
            { 
                { typeof(Int16),EnumVar.VTYPE_I2 },
                {typeof(Int32),EnumVar.VTYPE_I4 },
                {typeof(float),EnumVar.VTYPE_R4 },
                {typeof(double),EnumVar.VTYPE_R8 },
                {typeof(decimal),EnumVar.VTYPE_Decimal},
                {typeof(bool),EnumVar.VTYPE_BOOL },
                {typeof(sbyte),EnumVar.VTYPE_I1 },
                {typeof(byte),EnumVar.VTYPE_UI1 },
                {typeof(UInt16),EnumVar.VTYPE_UI2},
                {typeof(UInt32),EnumVar.VTYPE_UI4},
                {typeof(Int64),EnumVar.VTYPE_I8},
                {typeof(UInt64),EnumVar.VTYPE_UI8},
                {typeof(char),EnumVar.VTYPE_CHAR},
                {typeof(string),EnumVar.VTYPE_PWSTR},
                {typeof(byte[]),EnumVar.VTYPE_BLOB},
                {typeof(DateTime),EnumVar.VTYPE_DATE},
                {typeof(AutoWrapClient),EnumVar.VTYPE_AutoWrap},
                {typeof(Guid),EnumVar.VTYPE_GUID}//,
             //   {typeof(AutoWrap),EnumVar.VTYPE_JSObject}
            };


        }

     public static DateTime ReadDateTime(BinaryReader stream)
        {
            long nVal = stream.ReadInt64();
            //get 64bit binary
            return DateTime.FromBinary(nVal);


        }

        public static void WriteDateTime(DateTime value,BinaryWriter stream)
        {
            long nVal = value.ToBinary();
            //get 64bit binary
             stream.Write(nVal);


        }
        public static byte[] ReadByteArray(BinaryReader stream)
        {
            var length = stream.ReadInt32();
            return stream.ReadBytes(length);

        }
      public static  object GetObject(BinaryReader stream, TCPClientConnector Connector)
        {
            
            // Считываем тип объекта
            EnumVar type =(EnumVar)stream.ReadByte();

            // В зависмости от типа считываем и преобразуем данные
            switch (type)
            {
                case EnumVar.VTYPE_EMPTY:
                case EnumVar.VTYPE_NULL: return null;
                case EnumVar.VTYPE_I2: return stream.ReadInt16();
                case EnumVar.VTYPE_I4: return stream.ReadInt32();
                case EnumVar.VTYPE_R4: return stream.ReadSingle();
                case EnumVar.VTYPE_R8: return stream.ReadDouble();
                case EnumVar.VTYPE_Decimal: return stream.ReadDecimal();
                case EnumVar.VTYPE_BOOL: return stream.ReadBoolean();
                case EnumVar.VTYPE_I1: return stream.ReadSByte();
                case EnumVar.VTYPE_UI1: return stream.ReadByte();
                case EnumVar.VTYPE_UI2: return stream.ReadUInt16();

                case EnumVar.VTYPE_UI4: return stream.ReadUInt32();

                case EnumVar.VTYPE_I8: return stream.ReadInt64();
                case EnumVar.VTYPE_UI8: return stream.ReadUInt64();
                case EnumVar.VTYPE_CHAR: return stream.ReadChar();
                case EnumVar.VTYPE_PWSTR: return stream.ReadString();

                case EnumVar.VTYPE_BLOB: return ReadByteArray(stream);
                case EnumVar.VTYPE_DATE: return ReadDateTime(stream);
                case EnumVar.VTYPE_GUID: return new Guid(stream.ReadBytes(16));


                case EnumVar.VTYPE_AutoWrap:
                        var Target= stream.ReadInt32();
                        var AW = new AutoWrapClient(Target, Connector);


                    return AW;
              
            }
            return null;
            }


    
        public static bool WriteObject(object Объект, BinaryWriter stream)
        {


            // Если null то записываем только VTYPE_NULL
            if (Объект == null)
            {

                stream.Write((byte)EnumVar.VTYPE_NULL);
                 return true;

            }

            // Если это RefParam то сериализуем значение из Value
            // Нужен для возвращения out значения в Value 
            if (Объект.GetType() == typeof(RefParam))
            {
                object value= ((RefParam)Объект).Value;
                return WriteObject(value, stream);
            }
            EnumVar type;

            // Ищем тип в словаре MatchTypes
            var res = MatchTypes.TryGetValue(Объект.GetType(), out type);


            // Если тип не поддерживаемый вызываем исключение
            if (!res) {

                throw new Exception("Неверный тип " + Объект.GetType().ToString());
                return false;
            }

            // Записываем тип объекта
            stream.Write((byte)type);

            // В зависимости от типа сериализуем объект
            switch (type)
            {
                case EnumVar.VTYPE_I2: stream.Write((Int16)Объект); break;
                case EnumVar.VTYPE_I4: stream.Write((Int32)Объект); break;
                case EnumVar.VTYPE_R4: stream.Write((float)Объект); break;
                case EnumVar.VTYPE_R8: stream.Write((double)Объект); break;
                case EnumVar.VTYPE_Decimal: stream.Write((decimal)Объект); break;
                case EnumVar.VTYPE_BOOL: stream.Write((bool)Объект); break;
                case EnumVar.VTYPE_I1: stream.Write((sbyte)Объект); break;
                case EnumVar.VTYPE_UI1: stream.Write((byte)Объект); break;
                case EnumVar.VTYPE_UI2: stream.Write((UInt16)Объект); break;

                case EnumVar.VTYPE_UI4: stream.Write((UInt32)Объект); break;

                case EnumVar.VTYPE_I8: stream.Write((Int64)Объект); break;
                case EnumVar.VTYPE_UI8: stream.Write((UInt64)Объект); break;
                case EnumVar.VTYPE_CHAR: stream.Write((char)Объект); break;
                case EnumVar.VTYPE_PWSTR: stream.Write((string)Объект); break;

                case EnumVar.VTYPE_BLOB: stream.Write((byte[])Объект); break;
                case EnumVar.VTYPE_DATE: WriteDateTime((DateTime)Объект, stream); break;
                case EnumVar.VTYPE_GUID: stream.Write(((Guid)Объект).ToByteArray()); break;
                case EnumVar.VTYPE_AutoWrap:
                    stream.Write(((AutoWrapClient)Объект).Target);
                    break;
                    
            }
            return true;
        }

    }

   

}
и солнце б утром не вставало, когда бы не было меня
Re[4]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 10:32
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, Serginio1, Вы писали:


S>>Угу а сервер кто писать будет? Вся прелесть в том, что серверную часть тебе даже писать не надо.


H>Ну вот тут уже надо смотреть что доступно в корке для общения со внешним миром. Написать один раз TCP-сервер и клиент с пулом соединений не очень трудно.


Вот здесь я уже писал протокол общения
http://rsdn.org/forum/dotnet/6703738.1
Автор: Serginio1
Дата: 20.02.17
и солнце б утром не вставало, когда бы не было меня
Re[2]: .Net Core, AppDomain, RPC свой велосипед
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.02.17 10:32
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Сил вложено немало. В итоге получилось поделие даже не хуже WCF.


Хуже, причем сильно хуже. Ты просто не понимаешь что такое WCF.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[3]: .Net Core, AppDomain, RPC свой велосипед
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.02.17 10:32
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> А какая огромная разница между Protobuf и Json?


Производительность.

S>Для JSON есть прекрасная библиотека


Нашел новую игрушку? Увы, но для остальных это не аргумент.

S>Граблей с маршалингом нет, затраты на рефлексию


Затраты на рефлексию, по результатам реальных замеров, это 90% всей работы при передаче по ip. При передаче по более быстрым каналам, особенно по CrossAppDomainChannel цифра вообще близка к 100%.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[3]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 10:33
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


S>>Сил вложено немало. В итоге получилось поделие даже не хуже WCF.


AVK>Хуже, причем сильно хуже. Ты просто не понимаешь что такое WCF.

Которого нет Net Core.

А конструктивная критика?
и солнце б утром не вставало, когда бы не было меня
Re[4]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 10:36
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


S>> А какая огромная разница между Protobuf и Json?




AVK>Производительность.

При межпроцессном взаимодействии разница ничтожна.
S>>Для JSON есть прекрасная библиотека

AVK>Нашел новую игрушку? Увы, но для остальных это не аргумент.


S>>Граблей с маршалингом нет, затраты на рефлексию


AVK>Затраты на рефлексию, по результатам реальных замеров, это 90% всей работы при передаче по ip. При передаче по более быстрым каналам, особенно по CrossAppDomainChannel цифра вообще близка к 100%.


Угу. При внутрипроссном взаимодействии 500 000 вызовов в секунду
В том же CEF при взаимодействии между JS кодом нативои и .Net Core 60 000 вызовов в секунду.
А по TCP всего 2000 вызовов в секунду.

Вот замеры
Кроссплатформенное использование классов .Net из неуправляемого кода. Или аналог IDispatch на Linux
CEF, ES6, Angular 2, TypeScript использование классов .Net Core. Создание кроссплатформенного GUI для .Net с помощью CEF

http://rsdn.org/forum/dotnet/6703738.1
Автор: Serginio1
Дата: 20.02.17
и солнце б утром не вставало, когда бы не было меня
Отредактировано 28.02.2017 10:46 Serginio1 . Предыдущая версия .
Re[5]: .Net Core, AppDomain, RPC свой велосипед
От: hardcase Пират http://nemerle.org
Дата: 28.02.17 10:37
Оценка:
Здравствуйте, Serginio1, Вы писали:

H>>Сообщения протокола известны статически. Непонятно какие типы не уйдут в сеть и не придут внезапно из сети.


S>Ну опять же тебе нужно писать сервер. При моем подходе писать сервер не надо. Загружаешь нужные сборки и работаешь с ними удаленного.


S>Я понимаю, что web Api наше все. А как с асинхронными методами, событиями?


У меня пока не стоит задача удаленного взаимодействия в .Net Core, но когда встанет, я буду смотреть в сторону Protobuf + MQ фреймворк, типа ZeroMQ или RabbitMQ. Но не исключено, чот сделаю свой велосипед на общей памяти вместо TCP/IP.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 10:44
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, Serginio1, Вы писали:


H>>>Сообщения протокола известны статически. Непонятно какие типы не уйдут в сеть и не придут внезапно из сети.


S>>Ну опять же тебе нужно писать сервер. При моем подходе писать сервер не надо. Загружаешь нужные сборки и работаешь с ними удаленного.


S>>Я понимаю, что web Api наше все. А как с асинхронными методами, событиями?


H>У меня пока не стоит задача удаленного взаимодействия в .Net Core, но когда встанет, я буду смотреть в сторону Protobuf + MQ фреймворк, типа ZeroMQ или RabbitMQ. Но не исключено, чот сделаю свой велосипед на общей памяти вместо TCP/IP.


Ну с в Net Core вроде обещали поддержку пайпов. Несложно переделать обмен по Tcp/ip. А чем тебе мой варианет не нравится?
и солнце б утром не вставало, когда бы не было меня
Re[4]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 11:15
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


S>> А какая огромная разница между Protobuf и Json?


AVK>Производительность.

JSON применяется только для круных объектов, чтобы заполнять их на клиенте
Dictionary<int, string> ClientDict = new Dictionary<int, string>()
        {
            [1] = "Один",
            [2] = "Второй2",
            [3] = "Один3"
        };

        var @Dictionary2 = wrap.GetType("System.Collections.Generic.Dictionary`2", "System.Collections");
        var @DictionaryIntString = wrap.GetGenericType(@Dictionary2, "System.Int32", "System.String");

        // Скопируем словарь на сервер
        // Закомментированы различные варианты
        // var dict = connector.CoryTo(@DictionaryIntString, ClientDict);
        // var dict = connector.CoryTo("System.Collections.Generic.Dictionary`2[System.Int32, System.String]", ClientDict);

        // Скопируем словарь на сервер
        var dict = connector.CoryTo(ClientDict);



Для всех остальных обычная бинарная сериализация

 stream.Write((byte)type);

            // В зависимости от типа сериализуем объект
            switch (type)
            {
                case EnumVar.VTYPE_I2: stream.Write((Int16)Объект); break;
                case EnumVar.VTYPE_I4: stream.Write((Int32)Объект); break;
                case EnumVar.VTYPE_R4: stream.Write((float)Объект); break;
                case EnumVar.VTYPE_R8: stream.Write((double)Объект); break;
                case EnumVar.VTYPE_Decimal: stream.Write((decimal)Объект); break;
                case EnumVar.VTYPE_BOOL: stream.Write((bool)Объект); break;
                case EnumVar.VTYPE_I1: stream.Write((sbyte)Объект); break;
                case EnumVar.VTYPE_UI1: stream.Write((byte)Объект); break;
                case EnumVar.VTYPE_UI2: stream.Write((UInt16)Объект); break;

                case EnumVar.VTYPE_UI4: stream.Write((UInt32)Объект); break;

                case EnumVar.VTYPE_I8: stream.Write((Int64)Объект); break;
                case EnumVar.VTYPE_UI8: stream.Write((UInt64)Объект); break;
                case EnumVar.VTYPE_CHAR: stream.Write((char)Объект); break;
                case EnumVar.VTYPE_PWSTR: stream.Write((string)Объект); break;

                case EnumVar.VTYPE_BLOB: stream.Write((byte[])Объект); break;
                case EnumVar.VTYPE_DATE: WriteDateTime((DateTime)Объект, stream); break;
                case EnumVar.VTYPE_GUID: stream.Write(((Guid)Объект).ToByteArray()); break;
                case EnumVar.VTYPE_AutoWrap:
                    stream.Write(((AutoWrapClient)Объект).Target);
                    break;
                    
            }
            return true;


S>>Для JSON есть прекрасная библиотека


AVK>Нашел новую игрушку? Увы, но для остальных это не аргумент.


JSON сериализация нужна для крупных объектов, что бы не заполнять их на сервере.

Если нужна скорость, то вручную сериализуй и десериализуй на сервере. Никто же не запрещает.
Я пока решил для объетов кроме вышеупомянутых не делать автоматическую сериализацию.


S>>Граблей с маршалингом нет, затраты на рефлексию


AVK>Затраты на рефлексию, по результатам реальных замеров, это 90% всей работы при передаче по ip. При передаче по более быстрым каналам, особенно по CrossAppDomainChannel цифра вообще близка к 100%.


Кстати не нашел пайпов для .Net Core. Может плохо искал?
и солнце б утром не вставало, когда бы не было меня
Re[5]: .Net Core, AppDomain, RPC свой велосипед
От: Tom Россия http://www.RSDN.ru
Дата: 28.02.17 11:48
Оценка:
S>Кстати не нашел пайпов для .Net Core. Может плохо искал?
https://docs.microsoft.com/en-us/dotnet/core/api/system.io.pipes ?
Народная мудрось
всем все никому ничего(с).
Re[6]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 11:55
Оценка:
Здравствуйте, Tom, Вы писали:

S>>Кстати не нашел пайпов для .Net Core. Может плохо искал?

Tom>https://docs.microsoft.com/en-us/dotnet/core/api/system.io.pipes ?

Ghb добавлении
using System​.IO​.Pipes
ругается на Pipes
В пакетах тоже нет.
Целевая платформа .NetCoreApp1.1
и солнце б утром не вставало, когда бы не было меня
Re[4]: .Net Core, AppDomain, RPC свой велосипед
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.02.17 12:57
Оценка:
Здравствуйте, Serginio1, Вы писали:

AVK>>Хуже, причем сильно хуже. Ты просто не понимаешь что такое WCF.

S> Которого нет Net Core.

Тем не менее это не повод говорить, что твой полурабочий велосипед лучше.

S> А конструктивная критика?


Для конструктивной критики надо разбираться, а на это сейчас у меня нет ни времени, ни желания.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: .Net Core, AppDomain, RPC свой велосипед
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.02.17 12:57
Оценка:
Здравствуйте, Serginio1, Вы писали:

AVK>>Производительность.

S> При межпроцессном взаимодействии разница ничтожна.

Как раз при межпроцессном разница огромна, потому что каналы очень быстрые и с минимальной латентностью.

S> Угу. При внутрипроссном взаимодействии 500 000 вызовов в секунду


А латентность?

S>А по TCP всего 2000 вызовов в секунду.


Ты просто не умеешь его готовить.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: .Net Core, AppDomain, RPC свой велосипед
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.02.17 12:59
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Ну опять же тебе нужно писать сервер.


Не знаю что ты там понимаешь под сервером, но tcp сервер пишется на дотнете в одно выражение.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[6]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 14:04
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


AVK>>>Производительность.

S>> При межпроцессном взаимодействии разница ничтожна.

AVK>Как раз при межпроцессном разница огромна, потому что каналы очень быстрые и с минимальной латентностью.


S>> Угу. При внутрипроссном взаимодействии 500 000 вызовов в секунду


AVK>А латентность?


S>>А по TCP всего 2000 вызовов в секунду.


AVK>Ты просто не умеешь его готовить.


Так вот я и спрашиваю как? Никто не отвечает
и солнце б утром не вставало, когда бы не было меня
Re[8]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 14:11
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


S>>Ghb добавлении

S>>using System?.IO?.Pipes
S>> ругается на Pipes

AVK>

AVK>Assembly
AVK>System.IO.Pipes.dll


Нашел в \.nuget\packages\System.IO.Pipes\4.3.0\ref\netstandard1.3\

Но студия не хочет этот пакет использовать почему то.
Ладно добью библиотеку если это хоть кому то нужно будет сделаю и для пайпов. Там переделать всего 2 метода для эвентов и асинхронных методов.
и солнце б утром не вставало, когда бы не было меня
Re[6]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 14:15
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


S>>Ну опять же тебе нужно писать сервер.


AVK>Не знаю что ты там понимаешь под сервером, но tcp сервер пишется на дотнете в одно выражение.


Ну не в одно. Но обработку запросов кто писать будет?

Здесь берешь любой класс из любой сборки и работаешь с ним как с родным. Сейчас еще бинарные операции добавлю.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 28.02.2017 14:17 Serginio1 . Предыдущая версия .
Re[6]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 14:25
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


S>>Ну опять же тебе нужно писать сервер.


AVK>Не знаю что ты там понимаешь под сервером, но tcp сервер пишется на дотнете в одно выражение.


Кстати не подскажешь как из VS 2017 на GitHub выйти. Показывает только
https://serginio1.visualstudio.com/defaultcollection/RPCProjects/RPCProjects%20Team/_git/RPCProjects
и солнце б утром не вставало, когда бы не было меня
Re[7]: .Net Core, AppDomain, RPC свой велосипед
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.02.17 15:18
Оценка:
Здравствуйте, Serginio1, Вы писали:

AVK>>Не знаю что ты там понимаешь под сервером, но tcp сервер пишется на дотнете в одно выражение.

S>Ну не в одно.

Именно что в одно.

S> Но обработку запросов кто писать будет?


Лямбды пока еще не отменили.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[7]: .Net Core, AppDomain, RPC свой велосипед
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.02.17 15:18
Оценка:
Здравствуйте, Serginio1, Вы писали:

AVK>>Ты просто не умеешь его готовить.

S> Так вот я и спрашиваю как?

Что как?

S> Никто не отвечает


Потому что ты вопросы задавать не умеешь.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[8]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 16:40
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


AVK>>>Ты просто не умеешь его готовить.

S>> Так вот я и спрашиваю как?

AVK>Что как?


S>> Никто не отвечает


AVK>Потому что ты вопросы задавать не умеешь.


Ну у меня сейчас каждый раз инициализируется соединение и разрыв после ответа.
Завтра посмотрю на постоянном соединении
и солнце б утром не вставало, когда бы не было меня
Re[8]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 16:45
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


AVK>>>Не знаю что ты там понимаешь под сервером, но tcp сервер пишется на дотнете в одно выражение.

S>>Ну не в одно.

AVK>Именно что в одно.


S>> Но обработку запросов кто писать будет?


AVK>Лямбды пока еще не отменили.

А лямбды кто писать будет?

По твоему и HTTP сервер тоже можно не писать.
Вот как сейчас выглядит обработка


static void SetResult(MemoryStream ms, NetworkStream ns)
        {
            ms.Position = 0;
            ns.Write(BitConverter.GetBytes((Int32)ms.Length), 0, 4);
            ms.CopyTo(ns);
            ns.Flush();


        }

 private void RunMethod(NetworkStream ns, MemoryStream ms, IPAddress adress)
        {
            using (BinaryReader br = new BinaryReader(ms))
            {
                var msRes = new MemoryStream();
                using(BinaryWriter bw= new BinaryWriter(msRes))
                { 
                    var cm = (CallMethod)br.ReadByte();
                   
                    switch (cm)
                    {
                        case CallMethod.CallFunc: CallAsFunc(br, bw); break;
                        case CallMethod.GetMember: GetPropVal(br, bw); break;
                        case CallMethod.SetMember: SetPropVal(br, bw); break;
                        case CallMethod.CallFuncAsync: CallAsyncFunc(br, bw, adress); break;
                        case CallMethod.CallDelegate: CallAsDelegate(br, bw); break;
                        case CallMethod.CallGenericFunc: CallAsGenericFunc(br, bw); break;
                        case CallMethod.GetWrapperForObjectWithEvents: GetWrapperForObjectWithEvents(br, bw, adress); break;
                        case CallMethod.GetIndex: GetIndex(br, bw); break;
                        case CallMethod.SetIndex: SetIndex(br, bw); break;
                        case CallMethod.IteratorNext: IteratorNext(br, bw); break;
                        case CallMethod.DeleteObjects: DeleteObjects(br, bw); break;

                    }

                    bw.Flush();
                    SetResult(msRes, ns);
                }

            }
        }
        private void ExecuteMethod(TcpClient client)
        {
            var adress=((IPEndPoint)client.Client.RemoteEndPoint).Address;
        //    client.Client.NoDelay = true;
            using (NetworkStream ns = client.GetStream())
            {

                // Получим данные с клиента и на основании этих данных
                //Создадим ДанныеДляКлиета1С котрый кроме данных содержит 
                //TcpClient для отправки ответа
                using (var br = new BinaryReader(ns))
                {
                    var streamSize = br.ReadInt32();

                    var res = br.ReadBytes(streamSize);

                    var ms = new MemoryStream(res);
                    ms.Position = 0;
                    RunMethod(ns, ms, adress);
                }



            }

        }




static bool  GetAW(BinaryReader br, BinaryWriter bw, out NetObjectToNative.AutoWrap  AW )
        {

            var Target = br.ReadInt32();

            AW = NetObjectToNative.AutoWrap.ObjectsList.GetValue(Target);

            if (AW == null)
            {
                SetError("Не найдена ссылка на объект", bw);

                return false;
            }

            return true;
        }

 public static bool CallAsFuncAll(BinaryReader br, BinaryWriter bw, out object result, bool WriteResult)
        {
            result = null;
            NetObjectToNative.AutoWrap AW;
            if (!GetAW(br, bw, out AW))
                return false;



            string MethodName = br.ReadString();
            var args = GetArrayParams(br);

            string Error;
            List<int> ChageParams = new List<int>();

           
            var res = AW.TryInvokeMember(MethodName, args, out result, ChageParams, out Error);
            if (!res)
            {
                SetError(Error, bw);
                return false;
            }

           if (WriteResult)
            {
                bw.Write(true);
                WorkWhithVariant.WriteObject(NetObjectToNative.AutoWrap.WrapObject(result), bw);
                WriteChandeParams(bw, args, ChageParams);


            }
            return true;
        }
и солнце б утром не вставало, когда бы не было меня
Отредактировано 28.02.2017 16:47 Serginio1 . Предыдущая версия .
Re[9]: .Net Core, AppDomain, RPC свой велосипед
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.02.17 16:50
Оценка:
Здравствуйте, Serginio1, Вы писали:

AVK>>Лямбды пока еще не отменили.

S> А лямбды кто писать будет?

Лямбды могут быть частью одного выражения.

S>По твоему и HTTP сервер тоже можно не писать.


По моему простенький HTTP сервер для RPC по отношению к остальным задачам не стоит выеденного яйца. Если что — я в свое время исходники HttpChannel почти наизусть знал.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[10]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 17:58
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


AVK>>>Лямбды пока еще не отменили.

S>> А лямбды кто писать будет?

AVK>Лямбды могут быть частью одного выражения.


То есть с клиента передаешь сериализованные лямбды на сервер, компилируешь и выполняешь на сервере?
S>>По твоему и HTTP сервер тоже можно не писать.

AVK>По моему простенький HTTP сервер для RPC по отношению к остальным задачам не стоит выеденного яйца. Если что — я в свое время исходники HttpChannel почти наизусть знал.


Прошу прощения неправильно выразился. В данном случае и мел ввиду сервис. То есть Web Api Controllers.

В моем случае можно специально не писать даже сборки. Ибо можно использовать динамическую компиляцию. Она кстати у меня используется для создания Proxy для подключения к событиям.

1С,.Net Core. Динамическая компиляция класса обертки для получения событий .Net объекта в 1С

.Net Core, 1C, динамическая компиляция, Scripting API

Правда в первый раз долго обрабатывает. Но затем приемлемо.
и солнце б утром не вставало, когда бы не было меня
Re[10]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.02.17 18:52
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


AVK>>>Лямбды пока еще не отменили.

S>> А лямбды кто писать будет?

AVK>Лямбды могут быть частью одного выражения.


Кстати дал бы ссылочку на правильную работу с Tcp.
Я так понимаю нужен кэш на постоянное соединение, так как есть вызовы из Эвеннтов а и задачи могут применяться.
Завтра сравню скорость с постоянным соединением и подключением . Но для аналога AppDomain нужны пайпы.
и солнце б утром не вставало, когда бы не было меня
Re: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.03.17 07:46
Оценка:
Здравствуйте, Serginio1, Вы писали:

Сделал поддержку перегрузки оператора


    // Test поддерки перегрузки операторов.
        //Взят отсюда https://professorweb.ru/my/csharp/charp_theory/level6/6_4.php
        public static void TestCallOperators(dynamic wrap)
        {

            var MyArr = wrap.GetType("TestDllForCoreClr.MyArr", "TestDll");
            var Point1 = MyArr._new(1, 12, -4);
            var Point2 = MyArr._new(0, -3, 18);

        Console.WriteLine("Координаты первой точки: " +
                Point1.x + " " + Point1.y + " " + Point1.z);
            Console.WriteLine("Координаты второй точки: " +
                Point2.x + " " + Point2.y + " " + Point2.z + "\n");

            var Point3 = Point1 + Point2;
        Console.WriteLine("\nPoint1 + Point2 = "
                + Point3.x + " " + Point3.y + " " + Point3.z);
            Point3 = Point1 - Point2;
            Console.WriteLine("Point1 - Point2 = "
                + Point3.x + " " + Point3.y + " " + Point3.z);
            Point3 = -Point1;
            Console.WriteLine("-Point1 = "
                + Point3.x + " " + Point3.y + " " + Point3.z);
            Point2++;
            Console.WriteLine("Point2++ = "
                + Point2.x + " " + Point2.y + " " + Point2.z);
            Point2--;
            Console.WriteLine("Point2-- = "
                + Point2.x + " " + Point2.y + " " + Point2.z);

     
        }

    }
и солнце б утром не вставало, когда бы не было меня
Re[8]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.03.17 09:54
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


AVK>>>Ты просто не умеешь его готовить.

S>> Так вот я и спрашиваю как?

AVK>Что как?


S>> Никто не отвечает


AVK>Потому что ты вопросы задавать не умеешь.


Сделал тесту с постоянным соединением и с подключением и разрывом на какждый запрос
http://rsdn.org/forum/network/6712077.1
Автор: Serginio1
Дата: 01.03.17


Разница на порядок. и составляет порядка 20 000 запросов в секунду. Что вполне приемлемо.
http://rsdn.org/forum/network/6712077.1
Автор: Serginio1
Дата: 01.03.17
и солнце б утром не вставало, когда бы не было меня
Re: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 02.03.17 08:01
Оценка:
Здравствуйте, Serginio1, Вы писали:

Ну вроде добил. Скорость обмена по Tcp/IP порядка 14 000 вызовов в секунду. В 1С порядка 20 на внутрипроцессном.

Хочу написать статью. И прошу совета какой пример показать в вау эффектом.

Например перегрузка операторов


// Test поддерки перегрузки операторов.
        //Взят отсюда https://professorweb.ru/my/csharp/charp_theory/level6/6_4.php
        public static void TestCallOperators(dynamic wrap)
        {
            // получим ти по строкому представлению TestDllForCoreClr.MyArr
            // Из сборки TestDll
            var MyArr = wrap.GetType("TestDllForCoreClr.MyArr", "TestDll");

            // Создадим объекты на стороне сервера
            // и получим ссылки на них
            var Point1 = MyArr._new(1, 12, -4);
            var Point2 = MyArr._new(0, -3, 18);


            // Все операции происходят на стороне сервера
            Console.WriteLine("Координаты первой точки: " +
                Point1.x + " " + Point1.y + " " + Point1.z);
            Console.WriteLine("Координаты второй точки: " +
                Point2.x + " " + Point2.y + " " + Point2.z + "\n");

            var Point3 = Point1 + Point2;
            Console.WriteLine("\nPoint1 + Point2 = "
                + Point3.x + " " + Point3.y + " " + Point3.z);
            Point3 = Point1 - Point2;
            Console.WriteLine("Point1 - Point2 = "
                + Point3.x + " " + Point3.y + " " + Point3.z);
            Point3 = -Point1;
            Console.WriteLine("-Point1 = "
                + Point3.x + " " + Point3.y + " " + Point3.z);
            Point2++;
            Console.WriteLine("Point2++ = "
                + Point2.x + " " + Point2.y + " " + Point2.z);
            Point2--;
            Console.WriteLine("Point2-- = "
                + Point2.x + " " + Point2.y + " " + Point2.z);


        }


Кроме первых трех строчек, работа с удаленным объектом как с родным.
и солнце б утром не вставало, когда бы не было меня
Re[2]: .Net Core, AppDomain, RPC свой велосипед
От: vorona  
Дата: 02.03.17 13:27
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>Хочу написать статью. И прошу совета какой пример показать в вау эффектом.


Нужно придумать реальную задачу которую удобно решить с помощью твоего велосипеда.
Re[3]: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 02.03.17 13:35
Оценка:
Здравствуйте, vorona, Вы писали:

V>Здравствуйте, Serginio1, Вы писали:


S>>Здравствуйте, Serginio1, Вы писали:


S>>Хочу написать статью. И прошу совета какой пример показать в вау эффектом.


V>Нужно придумать реальную задачу которую удобно решить с помощью твоего велосипеда.


На самом деле это замена AppDomain. Смысл, что то сделать и выгрузить.
Второе это управление приложением из другого приложения например через статические методы и свойства.
и солнце б утром не вставало, когда бы не было меня
Re: .Net Core, AppDomain, RPC свой велосипед
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 03.03.17 07:04
Оценка:
Здравствуйте, Serginio1, Вы писали:

Надеюсь на помощь в примеров с вау эффектом для удаленного вызова.

Например можно выводить сообщение в консоли сервера


string typeStr = typeof(Console).AssemblyQualifiedName;
   var _Console = wrap.GetType(typeStr);// Получим тип на сервере по имени
   // "Hello from Client" будет выведено в консоле сервера
    _Console.WriteLine("Hello from Client");
и солнце б утром не вставало, когда бы не было меня
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.