コード例 #1
0
ファイル: RPCPeer.cs プロジェクト: kenkendk/LeanIPC
        /// <summary>
        /// Invokes a method remotely, and returns the result
        /// </summary>
        /// <returns>The result of the remote invocation.</returns>
        /// <param name="handle">The remote instance handle, or zero for null.</param>
        /// <param name="method">The method to invoke remotely.</param>
        /// <param name="arguments">The values given to the method when invoked.</param>
        /// <param name="isWrite">If set to <c>true</c> this is a write field or property request.</param>
        public Task <object> InvokeRemoteMethodAsync(long handle, System.Reflection.MemberInfo method, object[] arguments, bool isWrite)
        {
            var methodstring = m_typeSerializer.GetShortDefinition(method);
            var type         = m_typeSerializer.GetShortTypeName(method.DeclaringType);

            Type[] methodtypes;
            if (method is System.Reflection.MethodInfo)
            {
                var mi = method as System.Reflection.MethodInfo;
                methodtypes = mi.GetParameters().Select(x => x.ParameterType).ToArray();
            }
            else if (method is System.Reflection.ConstructorInfo)
            {
                var ci = method as System.Reflection.ConstructorInfo;
                methodtypes = ci.GetParameters().Select(x => x.ParameterType).ToArray();
            }
            else if (method is System.Reflection.FieldInfo)
            {
                if (isWrite)
                {
                    methodtypes = new Type[] { ((System.Reflection.FieldInfo)method).FieldType }
                }
                ;
                else
                {
                    methodtypes = new Type[0];
                }
            }
            else if (method is System.Reflection.PropertyInfo)
            {
                var pi         = method as System.Reflection.PropertyInfo;
                var indexTypes = pi.GetIndexParameters().Select(x => x.ParameterType);
                if (isWrite)
                {
                    indexTypes = new Type[] { pi.PropertyType }
                }
コード例 #2
0
        private static async Task ListenForRequests(RPCPeer peer, string prefix, string path)
        {
            Program.DebugConsoleOutput($"Setting up listener ...");

            var tp = new TypeSerializer(false, false);

            var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);

            socket.Connect(new SockRock.UnixEndPoint(prefix + path + "_fd"));

            Program.DebugConsoleOutput($"Connected to fd socket, reading initial data");

            SpawnedServer server;

            // Start by reading and verifying the protocol intial data
            var buffer = new byte[1024];
            var count  = socket.Receive(buffer);

            Program.DebugConsoleOutput($"Got protocol data with {count} bytes");

            using (var ms = new System.IO.MemoryStream(buffer, 0, count, false))
                using (var bcs = new BinaryConverterStream(ms, tp, false))
                {
                    var desc = await bcs.ReadAnyAsync <InitialProtocolDescription>();

                    if (desc.Version != 1)
                    {
                        throw new Exception($"Expected protocol version 1, but got {desc.Version}");
                    }
                    if (desc.RequestSignature != tp.GetShortTypeName(typeof(SocketRequest)))
                    {
                        throw new Exception($"Expected type name to be {tp.GetShortTypeName(typeof(SocketRequest))}, but it was {desc.RequestSignature}");
                    }
                    if (!peer.RemoteHandler.TryGetLocalObject(desc.ServerHandle, out var obj) || obj == null)
                    {
                        throw new Exception($"Unable to find the instance with the given handle: {desc.ServerHandle}");
                    }
                    server = obj as SpawnedServer;
                    if (server == null)
                    {
                        throw new Exception($"Unable to find the instance with the given handle: {desc.ServerHandle}, got something that is not a server ...");
                    }
                }

            Program.DebugConsoleOutput($"Protocol verification completed, starting main loop");

            // Prepare the handle
            var rchandle = socket.Handle.ToInt32();

            try
            {
                // Use a single allocated buffer for all requests
                using (var ms = new System.IO.MemoryStream())
                    using (var bcs = new BinaryConverterStream(ms, tp, false))
                    {
                        Program.DebugConsoleOutput("{0} Entering main loop", System.Diagnostics.Process.GetCurrentProcess().Id);
                        while (socket.Connected)
                        {
                            try
                            {
                                // Get the next request from the socket
                                Program.DebugConsoleOutput("{0} Getting file handle", System.Diagnostics.Process.GetCurrentProcess().Id);
                                var req = SockRock.ScmRightsImplementation.recv_fds(rchandle);
                                if (req == null)
                                {
                                    Program.DebugConsoleOutput("{0} Socket closed", System.Diagnostics.Process.GetCurrentProcess().Id);
                                    break;
                                }

                                Program.DebugConsoleOutput("{0} Got request, parsing ...", System.Diagnostics.Process.GetCurrentProcess().Id);

                                // Copy the buffer into the stream we read from
                                ms.Position = 0;
                                ms.Write(req.Item2, 0, req.Item2.Length);
                                ms.Position = 0;

                                // Extract the data
                                var data = await bcs.ReadAnyAsync <SocketRequest>();

                                Program.DebugConsoleOutput("{0}, Decoded request, local handle is {1} remote handle is {2}", System.Diagnostics.Process.GetCurrentProcess().Id, req.Item1[0], data.Handle);

                                // All set, fire the request
                                Task.Run(
                                    () => server.HandleRequestSimple(req.Item1[0], new IPEndPoint(IPAddress.Parse(data.RemoteIP), data.RemotePort), data.LogTaskID)
                                    ).ContinueWith(
                                    _ => Program.DebugConsoleOutput("{0}: Request handling completed", System.Diagnostics.Process.GetCurrentProcess().Id)
                                    );
                            }
                            catch (Exception ex)
                            {
                                Program.ConsoleOutput("{0}: Processing failed: {1}", System.Diagnostics.Process.GetCurrentProcess().Id, ex);
                                return;
                            }
                        }
                    }
            }
            finally
            {
                var st = DateTime.Now;
                Program.DebugConsoleOutput("{0}: Stopping spawned process", System.Diagnostics.Process.GetCurrentProcess().Id);
                server.Stop(TimeSpan.FromMinutes(5));
                Program.DebugConsoleOutput("{0}: Stopped spawned process in {1}", System.Diagnostics.Process.GetCurrentProcess().Id, DateTime.Now - st);
                peer.Dispose();
                Program.DebugConsoleOutput("{0}: Stopped peer in {1}", System.Diagnostics.Process.GetCurrentProcess().Id, DateTime.Now - st);
            }
        }