public async Task AttachSecondProxy() { var streams = FullDuplexStream.CreateStreams(); var server = new Server(); var serverRpc = JsonRpc.Attach(streams.Item2, server); var clientRpc = new JsonRpc(streams.Item1, streams.Item1); var client1 = clientRpc.Attach <IServer>(); var client2 = clientRpc.Attach <IServer2>(); clientRpc.StartListening(); Assert.Equal(3, await client1.AddAsync(1, 2)); Assert.Equal(6, await client2.MultiplyAsync(2, 3)); }
public async Task RPCMethodNameSubstitutionByOptions() { var streams = FullDuplexStream.CreateStreams(); this.serverStream = streams.Item1; this.clientStream = streams.Item2; var camelCaseOptions = new JsonRpcProxyOptions { MethodNameTransform = CommonMethodNameTransforms.CamelCase }; var prefixOptions = new JsonRpcProxyOptions { MethodNameTransform = CommonMethodNameTransforms.Prepend("ns.") }; // Construct two client proxies with conflicting method transforms to prove that each instance returned retains its unique options. var clientRpc = new JsonRpc(this.clientStream, this.clientStream); var clientRpcWithCamelCase = clientRpc.Attach <IServer3>(camelCaseOptions); var clientRpcWithPrefix = clientRpc.Attach <IServer3>(prefixOptions); clientRpc.StartListening(); // Construct the server to only respond to one set of method names for now to confirm that the client is sending the right one. this.serverRpc = new JsonRpc(this.serverStream, this.serverStream); this.serverRpc.AddLocalRpcTarget(this.server, new JsonRpcTargetOptions { MethodNameTransform = camelCaseOptions.MethodNameTransform }); this.serverRpc.StartListening(); Assert.Equal("Hi!", await clientRpcWithCamelCase.SayHiAsync()); // "sayHiAsync" await Assert.ThrowsAsync <RemoteMethodNotFoundException>(() => clientRpcWithPrefix.SayHiAsync()); // "ns.SayHiAsync" #if !NETCOREAPP1_0 // skip attribute-based renames where not supported Assert.Equal("ANDREW", await clientRpcWithCamelCase.ARoseByAsync("andrew")); // "anotherName" await Assert.ThrowsAsync <RemoteMethodNotFoundException>(() => clientRpcWithPrefix.ARoseByAsync("andrew")); // "ns.AnotherName" #endif // Prepare the server to *ALSO* accept method names with a prefix. this.serverRpc.AllowModificationWhileListening = true; this.serverRpc.AddLocalRpcTarget(this.server, new JsonRpcTargetOptions { MethodNameTransform = prefixOptions.MethodNameTransform }); // Retry with our second client proxy to send messages which the server should now accept. Assert.Equal("Hi!", await clientRpcWithPrefix.SayHiAsync()); // "ns.SayHiAsync" #if !NETCOREAPP1_0 // skip attribute-based renames where not supported Assert.Equal("ANDREW", await clientRpcWithPrefix.ARoseByAsync("andrew")); // "ns.AnotherName" #endif }
/// <summary> /// Registers Rpc-related services with the Dependency Injection provider /// </summary> private void ConfigureRpcServices(IServiceCollection services) { // Register our RPC services and tie it to a sample service services.AddSingleton <IRpcService>((services) => { var deviceClient = services.GetService <DeviceClient>(); var registration = services.GetService <IDeviceRegistrationProvider>(); var handler = new DispatchingClientMessageHandler(); var jsonRpc = new JsonRpc(handler); // Receive deviceClient.SetMethodHandlerAsync(_ConfigurationOptions.RpcMethodName, (request, context) => { handler.Dispatch(request.DataAsJson, registration.DeviceId); return(Task.FromResult(new MethodResponse(new byte[0], 200))); }, null).ConfigureAwait(false).GetAwaiter().GetResult(); // Send handler.SendAsync = async(message, clientId) => { var iotMessage = new Message(Encoding.UTF8.GetBytes(message)); await deviceClient.SendEventAsync(iotMessage); }; jsonRpc.StartListening(); return(jsonRpc.Attach <IRpcService>()); }); }
public LSPServer(Stream sender, Stream reader, Dictionary <string, DiagnosticSeverity> initialDiagnostics = null) { target = new LanguageServerTarget(this); rpc = JsonRpc.Attach(sender, reader, target); rpc.Disconnected += OnRpcDisconnected; diagnostics = initialDiagnostics; }
public async Task Run(T host) { while (true) { var stream = CreateStream(); await stream.WaitForConnectionAsync(); _ = Task.Run(async() => { try { ConnectionStateChanged?.Invoke(this, true); this.rpc = JsonRpc.Attach(stream, host); await this.rpc.Completion; } catch (ObjectDisposedException) { } catch (IOException) { } catch (Exception ex) { Log.Exception(ex); } ConnectionStateChanged?.Invoke(this, false); this.rpc.Dispose(); await stream.DisposeAsync(); }); } }
public void InternalInterface() { // When implementing internal interfaces work, fill out this test to actually invoke it. var streams = FullDuplexStream.CreateStreams(); Assert.Throws <TypeLoadException>(() => JsonRpc.Attach <IServerInternal>(streams.Item1)); }
public void NonTaskReturningMethod() { var streams = FullDuplexStream.CreateStreams(); var exception = Assert.Throws <NotSupportedException>(() => JsonRpc.Attach <IServerWithNonTaskReturnTypes>(streams.Item1)); this.Logger.WriteLine(exception.Message); }
public async Task BurstInvokeMessages(Stream serverStream, Stream clientStream) { var server = new Server(); using (JsonRpc.Attach(serverStream, server)) using (var client = JsonRpc.Attach(clientStream)) { // warmup await client.InvokeAsync("NoOp"); const int maxIterations = 10000; var invokeTasks = new List <Task>(maxIterations); var timer = Stopwatch.StartNew(); int i; for (i = 0; i < maxIterations; i++) { invokeTasks.Add(client.InvokeAsync("NoOp")); if (timer.ElapsedMilliseconds > 2000 && i > 0) { // It's taking too long to reach maxIterations. Break out. break; } } await Task.WhenAll(invokeTasks); timer.Stop(); this.logger.WriteLine($"{i} iterations completed in {timer.ElapsedMilliseconds} ms."); this.logger.WriteLine($"Rate: {i / timer.Elapsed.TotalSeconds} invocations per second."); this.logger.WriteLine($"Overhead: {(double)timer.ElapsedMilliseconds / i} ms per invocation."); } }
static async Task Main(string[] args) { var process = Process.Start(new ProcessStartInfo("ServerApp.exe") { CreateNoWindow = false, WindowStyle = ProcessWindowStyle.Normal, RedirectStandardError = true, RedirectStandardInput = true, RedirectStandardOutput = true, UseShellExecute = false, }); var server = JsonRpc.Attach <IService>(process.StandardInput.BaseStream, process.StandardOutput.BaseStream); try { await server.ExecuteAsync(); } catch (Exception ex) when(ex.InnerException is ServiceException se && se.ServiceKind == ServiceKind.Infrastructure) { // NOTE: client can access the actual inner exception, also get typed custom data // as well as the generic exception Data bag too. Console.WriteLine($"{se.Message}: {se.EventId} ({se.ServiceKind}, from {se.Data["Caller"]})"); } Console.WriteLine("Enter to exit client and server."); Console.ReadLine(); await server.StopAsync(); } }
public async Task Main() { while (true) { try { await this.stream.WaitForConnectionAsync(); IsConnected = true; this.rpc = JsonRpc.Attach(this.stream, Instance); this.rpc.Disconnected += (sender, e) => this.stream.Dispose(); await this.rpc.Completion; } catch (ObjectDisposedException) { Reset(); } catch (IOException) { Reset(); } catch (Exception ex) { Log.Exception(ex); Reset(); } } }
public async Task Connect() { await stream.ConnectAsync(); IsConnected = true; Instance = JsonRpc.Attach <T>(stream); }
static async Task Main(string[] args) { using (var webSocket = new ClientWebSocket()) { Console.WriteLine("正在与服务端建立连接..."); var uri = new Uri("ws://localhost:5000/rpc/greeter"); await webSocket.ConnectAsync(uri, CancellationToken.None); Console.WriteLine("已建立连接"); Console.WriteLine("开始向服务端发送消息..."); var messageHandler = new WebSocketMessageHandler(webSocket); var greeterClient = JsonRpc.Attach <IGreeter>(messageHandler); var request = new HelloRequest { Name = "精致码农" }; var response = await greeterClient.SayHelloAsync(request); Console.WriteLine($"收到来自服务端的响应:{response.Message}"); Console.WriteLine("正在断开连接..."); await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "断开连接", CancellationToken.None); Console.WriteLine("已断开连接"); } Console.ReadKey(); }
static async Task Main(string[] args) { Console.WriteLine("正在与服务端建立连接..."); var tcpClient = new TcpClient("localhost", 6000); var jsonRpcStream = tcpClient.GetStream(); Console.WriteLine("已建立连接"); var messageFormatter = new JsonMessageFormatter(Encoding.UTF8); var messageHandler = new LengthHeaderMessageHandler(jsonRpcStream, jsonRpcStream, messageFormatter); var greeterClient = JsonRpc.Attach <IGreeter>(messageHandler); Console.WriteLine("开始向服务端发送消息..."); var request = new HelloRequest { Name = "精致码农" }; var response = await greeterClient.SayHelloAsync(request); Console.WriteLine($"收到来自服务端的响应:{response.Message}"); Console.WriteLine(response.Message); Console.WriteLine("正在断开连接..."); jsonRpcStream.Close(); Console.WriteLine("已断开连接"); Console.ReadKey(); }
async Task MainAsync(string[] args) { Console.Error.WriteLine("Connecting to server " + args[0]); var server_executable = args[0]; var working_directory = Directory.GetCurrentDirectory(); var server_arguments = String.Join(" ", SubArray(args, 1)); TextReader x = System.Console.In as TextReader; ProcessStartInfo info = new ProcessStartInfo(); info.FileName = server_executable; info.WorkingDirectory = working_directory; info.Arguments = server_arguments; info.RedirectStandardInput = true; info.RedirectStandardOutput = true; info.UseShellExecute = false; info.CreateNoWindow = false; process = new Process(); process.StartInfo = info; if (!process.Start()) { System.Console.Error.WriteLine("Failure in spawning process."); return; } // Set up listening of client reader with stdin. stdin = Console.OpenStandardInput(); stdout = Console.OpenStandardOutput(); process_stdin = process.StandardOutput.BaseStream; process_stdout = process.StandardInput.BaseStream; rpc_client = JsonRpc.Attach(stdout, stdin, new LanguageServerTarget("client")); rpc_server = JsonRpc.Attach(process_stdout, process_stdin, new LanguageServerTarget("server")); await Task.Delay(-1); }
public void Run() { Logger.Log("PowerShellConsoleHost starting..."); Stream sender = Console.OpenStandardOutput(); Stream reader = Console.OpenStandardInput(); host = new PowerShellHost(); dte = new DTE(); ConsoleHostServices.Initialize(dte); var initialSessionState = CreateInitialSessionState(); runspace = RunspaceFactory.CreateRunspace(host, initialSessionState); runspace.Open(); rpc = JsonRpc.Attach(sender, reader, this); rpc.Disconnected += OnRpcDisconnected; JsonRpcProvider.Rpc = rpc; Logger.Log("PowerShellConsoleHost running..."); rpc.Completion.Wait(); }
private async Task <List <VSPublishSymbolParams> > GetVsSearchResultsAsync(Solution solution, string server, string query) { var client = (InProcRemoteHostClient)(await InProcRemoteHostClient.CreateAsync(solution.Workspace, runCacheCleanup: false)); var document = solution.Projects.First().Documents.First(); await UpdatePrimaryWorkspace(client, solution.WithDocumentFilePath(document.Id, @"c:\" + document.FilePath)); var callback = new Callback(); using (var jsonRpc = JsonRpc.Attach(await client.RequestServiceAsync(server), callback)) { var result = await jsonRpc.InvokeWithCancellationAsync <JObject>( Methods.InitializeName, new object[] { new InitializeParams() }, CancellationToken.None); Assert.True(result["capabilities"]["workspaceStreamingSymbolProvider"].ToObject <bool>()); var symbolResult = await jsonRpc.InvokeWithCancellationAsync <VSBeginSymbolParams>( VSSymbolMethods.WorkspaceBeginSymbolName, new object[] { query, 0 }, CancellationToken.None); } return(callback.Results); }
private static async Task RunClient(TcpClient client, Server instance, CancellationToken token) { var jsonRpc = JsonRpc.Attach(client.GetStream(), instance); token.Register(() => jsonRpc.Dispose()); await jsonRpc.Completion; }
public JsonRpcClient(Stream stream, object callbackTarget, bool useThisAsCallback) { var target = useThisAsCallback ? this : callbackTarget; _rpc = JsonRpc.Attach(stream, target); _rpc.Disconnected += OnDisconnected; }
public async Task ChattyPerf(Stream serverStream, Stream clientStream) { using (JsonRpc.Attach(serverStream, new Server())) using (var client = JsonRpc.Attach(clientStream)) { // warmup await client.InvokeAsync("NoOp"); const int maxIterations = 10000; var timer = Stopwatch.StartNew(); int i; for (i = 0; i < maxIterations; i++) { await client.InvokeAsync("NoOp"); if (timer.ElapsedMilliseconds > 2000 && i > 0) { // It's taking too long to reach maxIterations. Break out. break; } } timer.Stop(); this.logger.WriteLine($"{i} iterations completed in {timer.ElapsedMilliseconds} ms."); this.logger.WriteLine($"Rate: {i / timer.Elapsed.TotalSeconds} invocations per second."); this.logger.WriteLine($"Overhead: {(double)timer.ElapsedMilliseconds / i} ms per invocation."); } }
public async Task Connect() { await stream.ConnectAsync().Caf(); rpc = JsonRpc.Attach(stream, this); await rpc.InvokeAsync(nameof(IRemoteVisualStudio.RegisterCodeLensDataPoint), owner.id).Caf(); }
public void ProxyTypeIsReused() { var streams = FullDuplexStream.CreateStreams(); var clientRpc = JsonRpc.Attach <IServerDerived>(streams.Item1); Assert.IsType(this.clientRpc.GetType(), clientRpc); }
public async Task SendMessageWithEncoding(string encodingName) { var rpcClient = JsonRpc.Attach(this.clientStream); rpcClient.Encoding = Encoding.GetEncoding(encodingName); await rpcClient.NotifyAsync("Foo"); rpcClient.Dispose(); var reader = new StreamReader(this.serverStream, Encoding.ASCII); var headerLines = new List <string>(); string line; while ((line = reader.ReadLine()) != string.Empty) { headerLines.Add(line); } this.Logger.WriteLine(string.Join(Environment.NewLine, headerLines)); // utf-8 headers may not be present because they are the default, per the protocol spec. if (encodingName != "utf-8") { Assert.Contains(headerLines, l => l.Contains($"charset={encodingName}")); } reader = new StreamReader(this.serverStream, Encoding.GetEncoding(encodingName)); string json = reader.ReadToEnd(); Assert.Equal('{', json[0]); }
public async Task ReceiveMessageWithEncoding(string encodingName) { var server = new Server(); var rpcServer = JsonRpc.Attach(this.serverStream, server); Encoding contentEncoding = Encoding.GetEncoding(encodingName); string jsonMessage = @"{""method"":""Foo"",""id"":1}"; byte[] message = contentEncoding.GetBytes(jsonMessage); // Write the header, which is always in ASCII. Encoding headerEncoding = Encoding.ASCII; var headerBuffer = new MemoryStream(); string header = $"Content-Length: {message.Length}\r\nContent-Type: text/plain; charset={encodingName}\r\n\r\n"; byte[] headerBytes = headerEncoding.GetBytes(header); await this.clientStream.WriteAsync(headerBytes, 0, headerBytes.Length, this.TimeoutToken); await this.clientStream.WriteAsync(message, 0, message.Length, this.TimeoutToken); // Wait for response. byte[] receiveBuffer = new byte[1]; await this.clientStream.ReadAsync(receiveBuffer, 0, 1, this.TimeoutToken); // just wait for the response to start. Assert.Equal(1, server.FooCalledCount); }
private async Task <JsonRpc> GetJsonRpcAsync(Task <Stream> rpcStreamTask) { var stream = await rpcStreamTask; var target = new TerminalEvent(this.package, this); return(JsonRpc.Attach(stream, target)); }
private async Task ConnectAsync() { await _stream.ConnectAsync().ConfigureAwait(false); _rpc = JsonRpc.Attach(_stream, this); await _rpc.InvokeAsync(nameof(IRemoteVisualStudioCodeLens.RegisterCodeLensDataPoint), _owner.UniqueIdentifier).ConfigureAwait(false); }
private static async Task ResponseToRpcRequestsAsync() { Stream inp = Console.OpenStandardInput(); Stream outp = Console.OpenStandardOutput(); var jsonRpc = JsonRpc.Attach(outp, inp, new ConfigureAuthentificationHandler()); await jsonRpc.Completion; }
public async Task NamingTransformsAreAppliedToEvents() { var streams = FullDuplexStream.CreateStreams(); this.serverStream = streams.Item1; this.clientStream = streams.Item2; var camelCaseOptions = new JsonRpcProxyOptions { EventNameTransform = CommonMethodNameTransforms.CamelCase }; var prefixOptions = new JsonRpcProxyOptions { EventNameTransform = CommonMethodNameTransforms.Prepend("ns.") }; // Construct two client proxies with conflicting method transforms to prove that each instance returned retains its unique options. var clientRpc = new JsonRpc(this.clientStream, this.clientStream); var clientRpcWithCamelCase = clientRpc.Attach <IServer>(camelCaseOptions); var clientRpcWithPrefix = clientRpc.Attach <IServer>(prefixOptions); clientRpc.StartListening(); // Construct the server to only respond to one set of method names for now to confirm that the client is sending the right one. this.serverRpc = new JsonRpc(this.serverStream, this.serverStream); this.serverRpc.AddLocalRpcTarget(this.server, new JsonRpcTargetOptions { EventNameTransform = camelCaseOptions.EventNameTransform }); this.serverRpc.StartListening(); var tcs = new TaskCompletionSource <EventArgs>(); EventHandler handler = (sender, args) => tcs.SetResult(args); clientRpcWithCamelCase.ItHappened += handler; this.server.OnItHappened(EventArgs.Empty); var actualArgs = await tcs.Task.WithCancellation(this.TimeoutToken); Assert.NotNull(actualArgs); clientRpcWithCamelCase.ItHappened -= handler; clientRpcWithPrefix.ItHappened += handler; tcs = new TaskCompletionSource <EventArgs>(); this.server.OnItHappened(EventArgs.Empty); await Assert.ThrowsAsync <TimeoutException>(() => tcs.Task.WithTimeout(ExpectedTimeout)); Assert.False(tcs.Task.IsCompleted); clientRpcWithPrefix.ItHappened -= handler; }
public async Task SendPipeWithoutMultiplexingStream() { (Stream, Stream)streamPair = FullDuplexStream.CreatePair(); var clientRpc = JsonRpc.Attach(streamPair.Item1); (IDuplexPipe, IDuplexPipe)somePipe = FullDuplexStream.CreatePipePair(); await Assert.ThrowsAsync <NotSupportedException>(() => clientRpc.InvokeWithCancellationAsync(nameof(Server.TwoWayPipeAsArg), new[] { somePipe.Item2 }, this.TimeoutToken)); }
private static async Task ActAsRpcClientAsync(Stream stream) { Console.WriteLine("Connected. Sending request..."); using var jsonRpc = JsonRpc.Attach(stream); int sum = await jsonRpc.InvokeAsync <int>("Add", 3, 5); Console.WriteLine($"3 + 5 = {sum}"); }
public void Attach_NonGeneric() { var streams = FullDuplexStream.CreateStreams(); var rpc = new JsonRpc(streams.Item1); var clientRpc = (IServerDerived)rpc.Attach(typeof(IServerDerived)); Assert.IsType(this.clientRpc.GetType(), clientRpc); }