Beispiel #1
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);
            }
        }
Beispiel #2
0
 /// <summary>
 /// Terminates the remote instance
 /// </summary>
 public void Stop()
 {
     ShouldStop = true;
     m_peer.Dispose();
 }