Example #1
0
        static void Main(string[] args)
        {
            CultureInfo.CurrentUICulture = CultureInfo.GetCultureInfo("en-us");
            Console.InputEncoding        = Encoding.UTF8;
            Console.OutputEncoding       = Encoding.UTF8;
            CommandLineArguments.ParseFrom(args);
            if (CommandLineArguments.WaitForDebugger)
            {
                while (!Debugger.IsAttached)
                {
                    Thread.Sleep(1000);
                }
                Debugger.Break();
            }
            var host           = BuildServiceHost();
            var serverHandler  = new StreamRpcServerHandler(host);
            var clientHandler  = new StreamRpcClientHandler();
            var client         = new JsonRpcClient(clientHandler);
            var serviceContext = new SandboxHost(client, CommandLineArguments.SandboxPath);

            serverHandler.DefaultFeatures.Set(serviceContext);
            // Messages come from Console
            ByLineTextMessageReader reader;
            ByLineTextMessageWriter writer;

            if (!string.IsNullOrEmpty(CommandLineArguments.RxHandle))
            {
                var pipeClient = new AnonymousPipeClientStream(PipeDirection.In, CommandLineArguments.RxHandle);
                reader = new ByLineTextMessageReader(pipeClient);
            }
            else
            {
                reader = new ByLineTextMessageReader(Console.In);
            }
            if (!string.IsNullOrEmpty(CommandLineArguments.TxHandle))
            {
                var pipeClient = new AnonymousPipeClientStream(PipeDirection.Out, CommandLineArguments.TxHandle);
                writer = new ByLineTextMessageWriter(pipeClient);
            }
            else
            {
                writer = new ByLineTextMessageWriter(Console.Out);
            }
            try
            {
                using (reader)
                    using (writer)
                        using (serverHandler.Attach(reader, writer))
                            using (clientHandler.Attach(reader, writer))
                            {
                                // Started up.
                                serviceContext.HostingClient.NotifyStarted();
                                // Wait for exit
                                serviceContext.Disposal.Wait();
                            }
            }
            catch (ObjectDisposedException)
            {
            }
        }
Example #2
0
        static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            // Here we use two connected streams to simulate the console I/O
            // Content written to streams.Item1 will be read from streams.Item2, vice versa.
            var streams = FullDuplexStream.CreateStreams();
            // Let's start the test client first.
            var clientTask = RunClientAsync(streams.Item2);
            // Configure & build service host
            var host = BuildServiceHost();
            // Messages come from Stream
            var serverHandler = new StreamRpcServerHandler(host);
            // Though it's suggested that all feature types be interface types, for sake of
            // simplicity, here we just use a concrete class.
            var session = new LibrarySessionFeature();

            serverHandler.DefaultFeatures.Set(session);
            // Connect the datablocks
            // If we want server to stop, just stop the source
            using (var reader = new ByLineTextMessageReader(streams.Item1))
                using (var writer = new ByLineTextMessageWriter(streams.Item1))
                    using (serverHandler.Attach(reader, writer))
                    {
                        // Wait for exit
                        session.CancellationToken.WaitHandle.WaitOne();
                    }
            Console.WriteLine("Server exited.");
            // Wait for the client to exit.
            clientTask.GetAwaiter().GetResult();
        }
Example #3
0
        public static async Task RunClientAsync(Stream clientStream)
        {
            await Task.Yield(); // We want this task to run on another thread.

            var clientHandler = new StreamRpcClientHandler();

            using (var reader = new ByLineTextMessageReader(clientStream))
                using (var writer = new ByLineTextMessageWriter(clientStream))
                    using (clientHandler.Attach(reader, writer))
                    {
                        var client  = new JsonRpcClient(clientHandler);
                        var builder = new JsonRpcProxyBuilder
                        {
                            ContractResolver = myContractResolver
                        };
                        var proxy = builder.CreateProxy <ILibraryService>(client);
                        ClientWriteLine("Add booksā€¦");
                        await proxy.PutBookAsync(new Book("Somewhere Within the Shadows", "Juan DĆ­az Canales & Juanjo Guarnido",
                                                          new DateTime(2004, 1, 1),
                                                          "1596878177"));

                        await proxy.PutBookAsync(new Book("Arctic Nation", "Juan DĆ­az Canales & Juanjo Guarnido",
                                                          new DateTime(2004, 1, 1),
                                                          "0743479351"));

                        ClientWriteLine("Available books:");
                        foreach (var isbn in await proxy.EnumBooksIsbn())
                        {
                            var book = await proxy.GetBookAsync(isbn);

                            ClientWriteLine(book);
                        }
                        ClientWriteLine("Attempt to query for an inexistent ISBNā€¦");
                        try
                        {
                            await proxy.GetBookAsync("test", true);
                        }
                        catch (JsonRpcRemoteException ex)
                        {
                            ClientWriteLine(ex);
                        }
                        ClientWriteLine("Attempt to pass some invalid argumentā€¦");
                        try
                        {
                            await proxy.PutBookAsync(null);
                        }
                        catch (JsonRpcRemoteException ex)
                        {
                            ClientWriteLine(ex);
                        }
                        ClientWriteLine("Will shut down server in 5 secondsā€¦");
                        await Task.Delay(5000);

                        proxy.Terminate();
                    }
        }
Example #4
0
        public async Task ByLineMessagesOverSocketsTest()
        {
            var serverListener = new TcpListener(IPAddress.Loopback, TcpLocalTestPort);

            serverListener.Start();
            try
            {
                using (var tcpClient = new TcpClient())
                {
                    var serverAsync = serverListener.AcceptTcpClientAsync();
                    await tcpClient.ConnectAsync(IPAddress.Loopback, TcpLocalTestPort);

                    using (var tcpServer = await serverAsync)
                        using (var ss = tcpServer.GetStream())
                            using (var cs = tcpClient.GetStream())
                            {
                                using (var clientReader = new ByLineTextMessageReader(cs))
                                    using (var clientWriter = new ByLineTextMessageWriter(cs))
                                        using (var serverReader = new ByLineTextMessageReader(ss))
                                            using (var serverWriter = new ByLineTextMessageWriter(ss))
                                                using (var server = new ServerTestHelper(this, serverReader, serverWriter,
                                                                                         StreamRpcServerHandlerOptions.None))
                                                    using (var client = new ClientTestHelper(clientReader, clientWriter))
                                                        using (var server1 = new ServerTestHelper(this, clientReader, clientWriter,
                                                                                                  StreamRpcServerHandlerOptions.None))
                                                            using (var client1 = new ClientTestHelper(serverReader, serverWriter))
                                                            {
                                                                async Task ClientTestAsync()
                                                                {
                                                                    await Task.Yield();

                                                                    await TestRoutines.TestStubAsync(client.ClientStub);

                                                                    await TestRoutines.TestStubAsync(client.ClientExceptionStub);
                                                                }
                                                                async Task Client1TestAsync()
                                                                {
                                                                    await Task.Yield();

                                                                    await TestRoutines.TestStubAsync(client1.ClientStub);

                                                                    await TestRoutines.TestStubAsync(client1.ClientExceptionStub);
                                                                }

                                                                await Task.WhenAll(ClientTestAsync(), Client1TestAsync());
                                                            }
                            }
                }
            }
            finally
            {
                serverListener.Stop();
            }
        }
 public async Task PartwiseStreamCancellationTest()
 {
     (var ss, var cs) = FullDuplexStream.CreatePair();
     using (var clientReader = new ByLineTextMessageReader(cs))
         using (var clientWriter = new ByLineTextMessageWriter(cs))
             using (var serverReader = new ByLineTextMessageReader(ss))
                 using (var serverWriter = new ByLineTextMessageWriter(ss))
                     using (var server = new ServerTestHelper(this, serverReader, serverWriter,
                                                              StreamRpcServerHandlerOptions.SupportsRequestCancellation))
                         using (var client = new ClientTestHelper(clientReader, clientWriter))
                         {
                             await TestRoutines.TestCancellationAsync(client.ClientCancellationStub);
                         }
 }
Example #6
0
        private async Task RunAsync()
        {
            var host          = BuildServiceHost();
            var serverHandler = new StreamRpcServerHandler(host);
            var clientHandler = new StreamRpcClientHandler();
            var client        = new JsonRpcClient(clientHandler);

            using (var pipe = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous))
            {
                var connectTask = pipe.ConnectAsync();
                hostingClient = BuildHostingClient(client);
                serverHandler.DefaultFeatures.Set(this);
                var reader = new ByLineTextMessageReader(pipe)
                {
                    LeaveReaderOpen = true
                };
                var writer = new ByLineTextMessageWriter(pipe)
                {
                    LeaveWriterOpen = true
                };

                Ambient = new SandboxAmbient(hostingClient, SandboxId);

                await connectTask;
                using (reader)
                    using (writer)
                        using (serverHandler.Attach(reader, writer))
                            using (clientHandler.Attach(reader, writer))
                            {
                                // Started up
                                hostingClient.NotifyStarted();
                                // Wait for disposal
                                await disposalTcs.Task;
                            }
            }
            // Dispose
            if (_ClientModule != null)
            {
                if (_ClientModule is IDisposable d)
                {
                    d.Dispose();
                }
                _ClientModule = null;
            }
            // Final cleanup.
            // The owner will unload appdomain so a ThreadAbortException should be thrown here.
            hostCallback.NotifySandboxDisposed(SandboxId);
        }
Example #7
0
 /// <param name="manualIo">Simply read messages from console, line by line,
 /// instead of using language server protocol's specification.</param>
 public ConsoleIoService(bool manualIo)
 {
     if (manualIo)
     {
         ConsoleMessageReader = new ByLineTextMessageReader(Console.In);
         ConsoleMessageWriter = new ByLineTextMessageWriter(Console.Out);
     }
     else
     {
         var cin  = Console.OpenStandardInput();
         var bcin = new BufferedStream(cin);
         var cout = Console.OpenStandardOutput();
         ConsoleMessageReader = new PartwiseStreamMessageReader(bcin);
         ConsoleMessageWriter = new PartwiseStreamMessageWriter(cout);
     }
 }
Example #8
0
        private async Task RunClientAsync(Stream clientStream)
        {
            await Task.Yield(); // We want this task to run on another thread.

            // Initialize the client connection to the RPC server.
            var clientHandler = new StreamRpcClientHandler();

            using (var reader = new ByLineTextMessageReader(clientStream))
                using (var writer = new ByLineTextMessageWriter(clientStream))
                    using (clientHandler.Attach(reader, writer))
                    {
                        var builder = new JsonRpcProxyBuilder
                        {
                            ContractResolver = MyContractResolver
                        };

                        var proxy = builder.CreateProxy <Shared.IFileMonitor>(new JsonRpcClient(clientHandler));

                        // Create the function hooks after connection to the server.
                        CreateHooks();

                        try
                        {
                            while (true)
                            {
                                Thread.Sleep(500);

                                if (_queue.Count > 0)
                                {
                                    string[] package = null;

                                    lock (_queue)
                                    {
                                        package = _queue.ToArray();

                                        _queue.Clear();
                                    }
                                    await proxy.OnCreateFile(package);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            ClientWriteLine(ex.ToString());
                        }
                    }
        }
        public async Task ServerHandlerTest()
        {
            var request = new RequestMessage(123, "add", JToken.FromObject(new { x = 20, y = 35 }));

            (var ss, var cs) = FullDuplexStream.CreatePair();
            using (var clientReader = new StreamReader(cs))
                using (var clientWriter = new StreamWriter(cs))
                    using (var serverReader = new ByLineTextMessageReader(ss))
                        using (var serverWriter = new ByLineTextMessageWriter(ss))
                        {
                            async Task <ResponseMessage> WaitForResponse()
                            {
                                var sw      = Stopwatch.StartNew();
                                var content = await clientReader.ReadLineAsync();

                                Output.WriteLine($"Received response in {sw.Elapsed}.");
                                return((ResponseMessage)Message.LoadJson(content));
                            }

                            async Task <ResponseMessage> SendRequest(MessageId messageId)
                            {
                                request.Id = messageId;
                                request.WriteJson(clientWriter);
                                clientWriter.WriteLine();
                                await clientWriter.FlushAsync();

                                var response = await WaitForResponse();

                                Assert.Equal(messageId, response.Id);
                                Assert.Null(response.Error);
                                Assert.Equal(55, (int)response.Result);
                                return(response);
                            }

                            using (var server = new ServerTestHelper(this, serverReader, serverWriter,
                                                                     StreamRpcServerHandlerOptions.None))
                            {
                                await SendRequest(123);
                                await SendRequest("abc");
                            }
                        }
        }
Example #10
0
        public void HandleConnection(IPC.IConnection connection)
        {
            Console.WriteLine($"Connection received from pipe {_pipeName}");

            var pipeServer = connection.ServerStream;

            IJsonRpcServiceHost host = BuildServiceHost(_service);

            var serverHandler = new StreamRpcServerHandler(host);

            serverHandler.DefaultFeatures.Set(_session);

            using (var reader = new ByLineTextMessageReader(pipeServer))
                using (var writer = new ByLineTextMessageWriter(pipeServer))
                    using (serverHandler.Attach(reader, writer))
                    {
                        // Wait for exit
                        _session.CancellationToken.WaitHandle.WaitOne();
                    }
        }
        public async Task ConsistentResponseSequenceTest()
        {
            (var ss, var cs) = FullDuplexStream.CreatePair();
            using (var clientReader = new ByLineTextMessageReader(cs))
                using (var clientWriter = new ByLineTextMessageWriter(cs))
                    using (var serverReader = new ByLineTextMessageReader(ss))
                        using (var serverWriter = new ByLineTextMessageWriter(ss))
                            using (var client = new ClientTestHelper(clientReader, clientWriter))
                            {
                                using (var server = new ServerTestHelper(this, serverReader, serverWriter,
                                                                         StreamRpcServerHandlerOptions.None))
                                {
                                    // The responses are ordered by the time of completion.
                                    var delayTask =
                                        client.ClientStub.DelayAsync(TimeSpan.FromMilliseconds(200), CancellationToken.None);
                                    var addTask = client.ClientStub.AddAsync(3, -4);
                                    var result  = await addTask;
                                    Assert.Equal(-1, result);
                                    // addTask completes first.
                                    Assert.False(delayTask.IsCompleted);
                                    await delayTask;
                                }
                                using (var server = new ServerTestHelper(this, serverReader, serverWriter,
                                                                         StreamRpcServerHandlerOptions.ConsistentResponseSequence))
                                {
                                    // The responses are in the same order as the requests.
                                    var delayTask =
                                        client.ClientStub.DelayAsync(TimeSpan.FromMilliseconds(200), CancellationToken.None);
                                    var addTask = client.ClientStub.AddAsync(10, 20);
                                    await Task.Delay(100);

                                    // addTask is held up.
                                    Assert.False(addTask.IsCompleted);
                                    await delayTask;
                                    var   result = await addTask;
                                    Assert.Equal(30, result);
                                }
                            }
        }
        public async Task PartwiseStreamInteropTest()
        {
            (var ss, var cs) = FullDuplexStream.CreatePair();
            using (var clientReader = new ByLineTextMessageReader(cs))
                using (var clientWriter = new ByLineTextMessageWriter(cs))
                    using (var serverReader = new ByLineTextMessageReader(ss))
                        using (var serverWriter = new ByLineTextMessageWriter(ss))
                            using (var server = new ServerTestHelper(this, serverReader, serverWriter,
                                                                     StreamRpcServerHandlerOptions.None))
                                using (var client = new ClientTestHelper(clientReader, clientWriter))
                                {
                                    var e = Assert.Raises <MessageEventArgs>(h => client.ClientHandler.MessageSending += h,
                                                                             h => client.ClientHandler.MessageSending -= h,
                                                                             () => client.ClientStub.One());
                                    Assert.Equal("one", ((RequestMessage)e.Arguments.Message).Method);
                                    e = Assert.Raises <MessageEventArgs>(h => client.ClientHandler.MessageReceiving += h,
                                                                         h => client.ClientHandler.MessageReceiving -= h,
                                                                         () => client.ClientStub.One());
                                    Assert.Equal(new JValue(1), ((ResponseMessage)e.Arguments.Message).Result);
                                    await TestRoutines.TestStubAsync(client.ClientStub);

                                    await TestRoutines.TestStubAsync(client.ClientExceptionStub);
                                }
        }
Example #13
0
        // If initialization failed, the whole instance should just be discarded.
        internal async Task InitializeAsync()
        {
            if (state != SandboxState.Created)
            {
                throw new InvalidOperationException();
            }
            var pipeName = "SandyBox." + Guid.NewGuid();
            var pipe     = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1,
                                                     PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

            disposables.Add(pipe);
            Id = await Owner.HostStub.CreateSandbox(Name, pipeName);

            var procReader = new ByLineTextMessageReader(pipe)
            {
                LeaveReaderOpen = true
            };

            disposables.Add(procReader);
            var procWriter = new ByLineTextMessageWriter(pipe)
            {
                LeaveWriterOpen = true
            };

            disposables.Add(procWriter);
            // Wait for sandbox to start up.
            using (var cts = new CancellationTokenSource(5000))
            {
                Message startedMessage = null;
                try
                {
                    await pipe.WaitForConnectionAsync(cts.Token);

                    startedMessage = await procReader.ReadAsync(m =>
                                                                m is RequestMessage rm && rm.Method == "NotifyStarted",
                                                                cts.Token);
                }
                catch (OperationCanceledException)
                {
                }
                if (startedMessage == null)
                {
                    throw new ExecutionHostException(Prompts.CannotStartExecutionHost_MissingNotifyStarted);
                }
            }
            // HOST
            var hostBuilder = new JsonRpcServiceHostBuilder();

            hostBuilder.Register <HostingClientService>();
            var host          = hostBuilder.Build();
            var serverHandler = new StreamRpcServerHandler(host);

            serverHandler.DefaultFeatures.Set <ISandboxContextFeature>(new SandboxContextFeature(Owner, this));
            disposables.Add(serverHandler.Attach(procReader, procWriter));

            // CLIENT
            var clientHandler = new StreamRpcClientHandler();

            RpcClient = new JsonRpcClient(clientHandler);
            disposables.Add(clientHandler.Attach(procReader, procWriter));
            SandboxStub = JsonRpcExecutionHost.ProxyBuilder.CreateProxy <ISandboxStub>(RpcClient);

            disposables.Reverse();      // Dispose in the reversed order.
            state = SandboxState.Started;
        }
Example #14
0
        private async Task <Process> StartProcessAsync()
        {
            Debug.Assert(!_Process.IsValueCreated); // Can be called only once.
            Debug.Assert(disposables == null);
            Directory.CreateDirectory(WorkingDirectory);
            Process process          = null;
            var     localDisposables = new List <IDisposable>();

            try
            {
                var txPipe = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable);
                localDisposables.Add(txPipe);
                var rxPipe = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);
                localDisposables.Add(rxPipe);
                process = StartExecutionProcess(txPipe, rxPipe);
                localDisposables.Add(process);
                txPipe.DisposeLocalCopyOfClientHandle();
                rxPipe.DisposeLocalCopyOfClientHandle();

                var procReader = new ByLineTextMessageReader(rxPipe);
                localDisposables.Add(procReader);
                localDisposables.Remove(rxPipe);
                var procWriter = new ByLineTextMessageWriter(txPipe);
                localDisposables.Add(procWriter);
                localDisposables.Remove(txPipe);
                // Wait for host to start up.
                using (var cts = new CancellationTokenSource(5000))
                {
                    Message startedMessage = null;
                    try
                    {
                        startedMessage = await procReader.ReadAsync(m =>
                                                                    m is RequestMessage rm && rm.Method == "NotifyStarted",
                                                                    cts.Token);
                    }
                    catch (OperationCanceledException)
                    {
                    }
                    if (startedMessage == null)
                    {
                        throw new ExecutionHostException(Prompts.CannotStartExecutionHost_MissingNotifyStarted);
                    }
                }

                //// HOST
                //var hostBuilder = new JsonRpcServiceHostBuilder();
                //// Currently this host does nothing.
                //var host = hostBuilder.Build();
                //var serverHandler = new StreamRpcServerHandler(host);
                //serverHandler.DefaultFeatures.Set<ISandboxContextFeature>(new SandboxContextFeature(this, null));
                //localDisposables.Add(serverHandler.Attach(procReader, procWriter));

                // CLIENT
                var clientHandler = new StreamRpcClientHandler();
                RpcClient = new JsonRpcClient(clientHandler);
                localDisposables.Add(clientHandler.Attach(procReader, procWriter));

                HostStub = ProxyBuilder.CreateProxy <IHostStub>(RpcClient);
                return(process);
            }
            catch (Exception ex)
            {
                if (process != null)
                {
                    try
                    {
                        if (!process.WaitForExit(1000))
                        {
                            process.Kill();
                        }
                    }
                    catch (Exception ex1)
                    {
                        throw new AggregateException(ex, ex1);
                    }
                }
                foreach (var d in localDisposables)
                {
                    try
                    {
                        d.Dispose();
                    }
                    catch (ObjectDisposedException)
                    {
                        // StreamWriter will attempt to flush before disposal,
                    }
                    catch (Exception ex1)
                    {
                        throw new AggregateException(ex, ex1);
                    }
                }
                localDisposables = null;
                if (ex is ExecutionHostException)
                {
                    throw;
                }
                throw new ExecutionHostException(Prompts.CannotStartExecutionHost, ex);
            }
            finally
            {
                if (localDisposables != null)
                {
                    disposables = localDisposables;
                }
            }
        }