예제 #1
0
        private Task NeedNewInstance(string password)
        {
            var             instanceTransporter = instanceTransporterCreator(password);
            var             instance            = instanceCreater();
            var             codeInvoker         = new CodeInvoker(instance, typeof(T));
            InstanceWrapper rootWrapper         = new InstanceWrapper(codeInvoker, instanceTransporter);

            return(Task.CompletedTask);
        }
예제 #2
0
        private InvokeResult GetInvokationResult(InvokeMessage message)
        {
            object data;

            try
            {
                data = invoker.Invoke(message, CreateRemoteInvoker);
            }
            catch (Exception ex)
            {
                return(InvokeResult.Exception(message.Id, ex));
            }
            if (data == null)
            {
                return(InvokeResult.Null(message.Id));
            }
            if (data is Stream stream)
            {
                return(InvokeResult.Stream(message.Id, stream));
            }
            if (PrimitiveTypes.Contains(data.GetType()))
            {
                return(InvokeResult.Primitive(message.Id, JToken.FromObject(data)));
            }

            var  codeInvoker = new CodeInvoker(data, data.GetType());
            long newId;

            //TODO lock need?
            lock (subWrappers)
            {
                newId = ++lastId;
                subWrappers[newId] = new InstanceWrapper(codeInvoker);
            }
            return(InvokeResult.HardObject(message.Id, newId));
        }
예제 #3
0
        public void Intercept(IInvocation invocation)
        {
            if (aborted)
            {
                throw new ServiceUnavailableException();
            }
            InvokeMessage message = new InvokeMessage
            {
                Id          = Guid.NewGuid(),
                MethodName  = invocation.Method.Name,
                SubObjectId = objectId,
                Args        = new Dictionary <string, Value>(),
                Streams     = new Dictionary <string, Stream>()
            };

            if (invocation.Method.Name == "Dispose" && wrapped)
            {
                Dispose();
                return;
            }

            int i = 0;

            foreach (var param in invocation.Method.GetParameters())
            {
                var argument = invocation.Arguments[i++];
                if (argument == null)
                {
                    message.Args[param.Name] = new Value {
                        Type = Messages.ValueType.Null
                    };
                }
                else
                if (argument is Stream stream)
                {
                    message.Streams[param.Name] = stream;
                    continue;
                }
                Value value = new Value();
                if (argument == null)
                {
                    value.Type = Messages.ValueType.Null;
                }
                else
                if (PrimitiveTypes.Contains(argument.GetType()))
                {
                    value.Type = Messages.ValueType.Primitive;
                    value.Data = JToken.FromObject(argument);
                }
                else
                {
                    value.Type = Messages.ValueType.HardObject;
                    CodeInvoker     newInvoker      = new CodeInvoker(argument, param.ParameterType);
                    InstanceWrapper instanceWrapper = new InstanceWrapper(newInvoker, transporter);
                    value.Data = instanceWrapper.Id;
                }
                message.Args[param.Name] = value;
            }
            var data = JsonConvert.SerializeObject(message, Formatting.Indented);

            Console.WriteLine(data);

            ManualResetEvent resetEvent = new ManualResetEvent(false);

            waiters.TryAdd(message.Id, new WaitPair {
                ResetEvent = resetEvent
            });

            transporter.SendMessage(message).Wait();

            while (!resetEvent.WaitOne(TimeSpan.FromSeconds(0.5)))
            {
                if (aborted)
                {
                    throw new ServiceUnavailableException();
                }
            }

            if (!waiters.TryRemove(message.Id, out var waitPair))
            {
                throw new Exception("Blya blya blya nety waitera!!!!");
            }
            var result = waitPair.Result;

            switch (result.ResultType)
            {
            case ResultType.Primitive:
                Console.WriteLine($"Primitive, value: {result.PrimitiveValue} for resuest {message.MethodName}");
                invocation.ReturnValue = result.PrimitiveValue.ToObject(invocation.Method.ReturnType);
                return;

            case ResultType.Null:
                Console.WriteLine($"null value for request {message.MethodName} or void method");
                return;

            case ResultType.Stream:
                Console.WriteLine($"Stream, length: {result.StreamValue.Length} for request {message.MethodName}");
                invocation.ReturnValue = result.StreamValue;
                return;

            case ResultType.Exception:
                throw new Exception(result.ExceptionMessage);

            case ResultType.HardObject:
                Console.WriteLine($"Hard object, id: {result.HardObjectId} for request {message.MethodName}");
                var worker = new RemoteWorker(transporter, result.HardObjectId, false);
                invocation.ReturnValue = Create(invocation.Method.ReturnType, worker);
                return;
            }
        }
예제 #4
0
 private InstanceWrapper(CodeInvoker invoker)
 {
     this.invoker    = invoker ?? throw new ArgumentNullException(nameof(invoker));
     subWrappers[id] = this;
 }
예제 #5
0
 public InstanceWrapper(CodeInvoker invoker, ITransporter transporter)
     : this(invoker)
 {
     transporter.OnReceiveMessge += RecieveMessage;
     this.transporter             = transporter;
 }