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"); } }
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(); }
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 ServerTestHelper(UnitTestBase owner, MessageReader reader, MessageWriter writer, StreamRpcServerHandlerOptions options) { ServiceHost = Utility.CreateJsonRpcServiceHost(owner); ServerHandler = new StreamRpcServerHandler(ServiceHost, options); ServerMessageReader = reader; ServerMessageWriter = writer; disposables.Add(ServerHandler.Attach(ServerMessageReader, ServerMessageWriter)); }
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"); } }
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); }
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(); } } }
private static int StartServerHandler(IComponentContext context) { var serviceHost = context.Resolve <IJsonRpcServiceHost>(); var handler = new StreamRpcServerHandler(serviceHost, StreamRpcServerHandlerOptions.ConsistentResponseSequence | StreamRpcServerHandlerOptions.SupportsRequestCancellation); var state = context.Resolve <SessionState>(); handler.DefaultFeatures.Set <ISessionStateFeature>(new SessionStateFeature(state)); var cio = context.Resolve <ConsoleIoService>(); using (handler.Attach(cio.ConsoleMessageReader, cio.ConsoleMessageWriter)) { var lifetime = context.Resolve <ServiceHostLifetime>(); lifetime.CancellationToken.WaitHandle.WaitOne(); } return(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 <IActionResult> Get() { if (HttpContext.WebSockets.IsWebSocketRequest) { var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); var serverHandler = new StreamRpcServerHandler(_JsonRpcServiceHost) { // This will make IJsonRpcServiceHost built with default JsonRpc.AspNetCore.JsonRpcOptions value works. // Its ServiceFactory needs HttpContext to work. DefaultFeatures = new SingleFeatureCollection <IAspNetCoreFeature>(AspNetCoreFeature.FromHttpContext(HttpContext)) }; using (var reader = new WebSocketMessageReader(webSocket)) using (var writer = new WebSocketMessageWriter(webSocket)) using (serverHandler.Attach(reader, writer)) { await reader.WebSocketClose; } return(new EmptyResult()); } return(BadRequest("Needs Websocket connection.")); }
// 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; }