static void Main(string[] args)
        {
            var debugMode = args.Any(a => a.Equals("--debug", StringComparison.OrdinalIgnoreCase));

#if WAIT_FOR_DEBUGGER
            while (!Debugger.IsAttached)
            {
                Thread.Sleep(1000);
            }
            Debugger.Break();
#endif
            StreamWriter logWriter = null;
            if (debugMode)
            {
                logWriter           = File.CreateText("messages-" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".log");
                logWriter.AutoFlush = true;
            }
            using (logWriter)
                using (var cin = Console.OpenStandardInput())
                    using (var bcin = new BufferedStream(cin))
                        using (var cout = Console.OpenStandardOutput())
                            using (var reader = new PartwiseStreamMessageReader(bcin))
                                using (var writer = new PartwiseStreamMessageWriter(cout))
                                {
                                    var contractResolver = new JsonRpcContractResolver
                                    {
                                        NamingStrategy          = new CamelCaseJsonRpcNamingStrategy(),
                                        ParameterValueConverter = new LanguageServiceParameterValueConverter(),
                                    };
                                    var clientHandler = new StreamRpcClientHandler();
                                    var client        = new JsonRpcClient(clientHandler);
                                    if (debugMode)
                                    {
                                        // We want to capture log all the LSP server-to-client calls as well
                                        clientHandler.MessageSending += (_, e) =>
                                        {
                                            lock (logWriter) logWriter.WriteLine("{0} <C{1}", Utility.GetTimeStamp(), e.Message);
                                        };
                                        clientHandler.MessageReceiving += (_, e) =>
                                        {
                                            lock (logWriter) logWriter.WriteLine("{0} >C{1}", Utility.GetTimeStamp(), e.Message);
                                        };
                                    }
                                    // Configure & build service host
                                    var session       = new LanguageServerSession(client, contractResolver);
                                    var host          = BuildServiceHost(logWriter, contractResolver, debugMode);
                                    var serverHandler = new StreamRpcServerHandler(host,
                                                                                   StreamRpcServerHandlerOptions.ConsistentResponseSequence |
                                                                                   StreamRpcServerHandlerOptions.SupportsRequestCancellation);
                                    serverHandler.DefaultFeatures.Set(session);
                                    // If we want server to stop, just stop the "source"
                                    using (serverHandler.Attach(reader, writer))
                                        using (clientHandler.Attach(reader, writer))
                                        {
                                            // Wait for the "stop" request.
                                            session.CancellationToken.WaitHandle.WaitOne();
                                        }
                                    logWriter?.WriteLine("Exited");
                                }
        }
Exemple #2
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)
            {
            }
        }
        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();
                    }
        }
Exemple #4
0
        public void Connect(bool debugMode)
        {
            var logWriter = CreateLogWriter(true);

            using (logWriter)
                using (var cin = Console.OpenStandardInput())
                    using (var bcin = new BufferedStream(cin))
                        using (var cout = Console.OpenStandardOutput())
                            using (var reader = new PartwiseStreamMessageReader(bcin))
                                using (var writer = new PartwiseStreamMessageWriter(cout)) {
                                    var contractResolver = new JsonRpcContractResolver {
                                        NamingStrategy          = new CamelCaseJsonRpcNamingStrategy(),
                                        ParameterValueConverter = new CamelCaseJsonValueConverter(),
                                    };
                                    var clientHandler = new StreamRpcClientHandler();
                                    var client        = new JsonRpcClient(clientHandler);
                                    if (debugMode)
                                    {
                                        // We want to capture log all the LSP server-to-client calls as well
                                        clientHandler.MessageSending += (_, e) => {
                                            lock (logWriter) {
                                                logWriter.WriteLine("<C{0}", e.Message);
                                            }
                                        };
                                        clientHandler.MessageReceiving += (_, e) => {
                                            lock (logWriter) {
                                                logWriter.WriteLine(">C{0}", e.Message);
                                            }
                                        };
                                    }

                                    var session = new LanguageServerSession(client, contractResolver);
                                    _serviceManager.AddService(new SettingsManager(_serviceManager));
                                    _serviceManager.AddService(new VsCodeClient(session.Client, _serviceManager));
                                    _serviceManager.AddService(new Controller(_serviceManager));

                                    // Configure & build service host
                                    var host          = BuildServiceHost(logWriter, contractResolver, debugMode);
                                    var serverHandler = new StreamRpcServerHandler(host,
                                                                                   StreamRpcServerHandlerOptions.ConsistentResponseSequence |
                                                                                   StreamRpcServerHandlerOptions.SupportsRequestCancellation);
                                    serverHandler.DefaultFeatures.Set(session);

                                    var cts = new CancellationTokenSource();
                                    // If we want server to stop, just stop the "source"
                                    using (serverHandler.Attach(reader, writer))
                                        using (clientHandler.Attach(reader, writer))
                                            using (new RConnection(_serviceManager, cts.Token)) {
                                                // Wait for the "stop" request.
                                                session.CancellationToken.WaitHandle.WaitOne();
                                                cts.Cancel();
                                            }
                                    logWriter?.WriteLine("Exited");
                                }
        }
Exemple #5
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);
        }
Exemple #6
0
 static void Main(string[] args)
 {
     using (Stream cin = Console.OpenStandardInput())
         using (BufferedStream bcin = new BufferedStream(cin))
             using (Stream cout = Console.OpenStandardOutput())
                 using (PartwiseStreamMessageReader reader = new PartwiseStreamMessageReader(bcin))
                     using (PartwiseStreamMessageWriter writer = new PartwiseStreamMessageWriter(cout))
                     {
                         JsonRpcContractResolver contractResolver = new JsonRpcContractResolver
                         {
                             NamingStrategy          = new CamelCaseJsonRpcNamingStrategy(),
                             ParameterValueConverter = new CamelCaseJsonValueConverter(),
                         };
                         StreamRpcClientHandler clientHandler = new StreamRpcClientHandler();
                         JsonRpcClient          client        = new JsonRpcClient(clientHandler);
                         clientHandler.MessageSending += (_, e) =>
                         {
                             Console.Error.WriteLine("Sending: " + e.Message);
                         };
                         clientHandler.MessageReceiving += (_, e) =>
                         {
                             Console.Error.WriteLine("Receiving: " + e.Message);
                         };
                         LanguageServerSession     session = new LanguageServerSession(client, contractResolver);
                         JsonRpcServiceHostBuilder builder = new JsonRpcServiceHostBuilder {
                             ContractResolver = contractResolver
                         };
                         builder.UseCancellationHandling();
                         builder.Register(typeof(Program).GetTypeInfo().Assembly);
                         builder.Intercept(async(context, next) =>
                         {
                             Console.Error.WriteLine("Request: " + context.Request);
                             await next();
                             Console.Error.WriteLine("Response: " + context.Response);
                         });
                         IJsonRpcServiceHost    host          = builder.Build();
                         StreamRpcServerHandler serverHandler = new StreamRpcServerHandler(host,
                                                                                           StreamRpcServerHandlerOptions.ConsistentResponseSequence | StreamRpcServerHandlerOptions.SupportsRequestCancellation);
                         serverHandler.DefaultFeatures.Set(session);
                         using (serverHandler.Attach(reader, writer))
                             using (clientHandler.Attach(reader, writer))
                             {
                                 // Wait for the "stop" request.
                                 session.CancellationToken.WaitHandle.WaitOne();
                             }
                     }
 }
Exemple #7
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 ClientTestHelper(MessageReader reader, MessageWriter writer)
            {
                ClientHandler       = new StreamRpcClientHandler();
                Client              = new JsonRpcClient(ClientHandler);
                ClientMessageReader = reader;
                ClientMessageWriter = writer;
                // We use positional parameters when issuing cancelRequest request. Just for more test coverage.
                Client.RequestCancelling += (_, e) => { Client.SendNotificationAsync("cancelRequest", new JArray(e.RequestId.Value), CancellationToken.None); };
                disposables.Add(ClientHandler.Attach(ClientMessageReader, ClientMessageWriter));

                var proxyBuilder = new JsonRpcProxyBuilder {
                    ContractResolver = Utility.DefaultContractResolver
                };

                ClientStub             = proxyBuilder.CreateProxy <ITestRpcContract>(Client);
                ClientExceptionStub    = proxyBuilder.CreateProxy <ITestRpcExceptionContract>(Client);
                ClientCancellationStub = proxyBuilder.CreateProxy <ITestRpcCancellationContract>(Client);
            }
        private static JsonRpcClient RpcClientFactory(IComponentContext context)
        {
            var cio        = context.Resolve <ConsoleIoService>();
            var handler    = new StreamRpcClientHandler();
            var disposable = handler.Attach(cio.ConsoleMessageReader, cio.ConsoleMessageWriter);
            var client     = new JsonRpcClient(handler);

            if (context.Resolve <ApplicationConfiguration>().Debug)
            {
                var logger = context.Resolve <ILoggerFactory>().CreateLogger("CLIENT");
                handler.MessageSending += (_, e) =>
                {
                    logger.LogTrace("< {@Request}", e.Message);
                };
                handler.MessageReceiving += (_, e) =>
                {
                    logger.LogTrace("> {@Response}", e.Message);
                };
            }
            return(client);
        }
Exemple #10
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;
        }
Exemple #11
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;
                }
            }
        }