public async Task Writing_MixedLineEndings() { var pipe = new Pipe(); var handler = new NewLineDelimitedMessageHandler(pipe.Writer, null, new JsonMessageFormatter()); // Use the handler to write out a couple messages with mixed line endings. await handler.WriteAsync(this.mockMessages[0], this.TimeoutToken); // CRLF handler.NewLine = NewLineDelimitedMessageHandler.NewLineStyle.Lf; await handler.WriteAsync(this.mockMessages[1], this.TimeoutToken); // LF await handler.DisposeAsync(); using var streamReader = new StreamReader(pipe.Reader.AsStream(), handler.Formatter.Encoding); string allMessages = await streamReader.ReadToEndAsync(); // Use CR and LF counts to quickly figure whether our new line styles were honored. Assert.Equal(3, allMessages.Split('\n').Length); Assert.Equal(2, allMessages.Split('\r').Length); // Now actually parse the messages. var msgJson = allMessages.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Select(m => JToken.Parse(m.Trim())).ToArray(); Assert.Equal(2, msgJson.Length); for (int i = 0; i < 2; i++) { Assert.Equal(this.mockMessages[i].RequestId.Number, msgJson[i]["id"] !.Value <int>()); } }
public async Task Reading_MixedLineEndings() { var pipe = new Pipe(); var handler = new NewLineDelimitedMessageHandler(null, pipe.Reader, new JsonMessageFormatter()); // Send messages with mixed line endings to the handler.. var testFormatter = new JsonMessageFormatter(); testFormatter.Serialize(pipe.Writer, this.mockMessages[0]); pipe.Writer.Write(testFormatter.Encoding.GetBytes("\n")); testFormatter.Serialize(pipe.Writer, this.mockMessages[1]); pipe.Writer.Write(testFormatter.Encoding.GetBytes("\r\n")); testFormatter.Serialize(pipe.Writer, this.mockMessages[2]); pipe.Writer.Write(testFormatter.Encoding.GetBytes("\r\n")); await pipe.Writer.FlushAsync(this.TimeoutToken); pipe.Writer.Complete(); // Assert that the handler can read each one. var readMessage1 = (JsonRpcRequest?)await handler.ReadAsync(this.TimeoutToken); Assert.Equal(this.mockMessages[0].RequestId, readMessage1 !.RequestId); Assert.Equal(this.mockMessages[0].Method, readMessage1.Method); var readMessage2 = (JsonRpcRequest?)await handler.ReadAsync(this.TimeoutToken); Assert.Equal(this.mockMessages[1].RequestId, readMessage2 !.RequestId); Assert.Equal(this.mockMessages[1].Method, readMessage2.Method); var readMessage3 = (JsonRpcRequest?)await handler.ReadAsync(this.TimeoutToken); Assert.Equal(this.mockMessages[2].RequestId, readMessage3 !.RequestId); Assert.Equal(this.mockMessages[2].Method, readMessage3.Method); Assert.Null(await handler.ReadAsync(this.TimeoutToken)); }
internal async Task ConnectAsync(CancellationToken cancellationToken) { Console.WriteLine("Connecting to server..."); var stream = new NamedPipeClientStream(".", "JsonRpcTest", PipeDirection.InOut, PipeOptions.Asynchronous); await stream.ConnectAsync(); var formatter = new JsonMessageFormatter(Encoding.UTF8); //formatter.ProtocolVersion = new Version(1, 0); var handler = new NewLineDelimitedMessageHandler(stream, stream, formatter) { NewLine = NewLineDelimitedMessageHandler.NewLineStyle.Lf }; var jsonRpc = new JsonRpc(handler); jsonRpc.StartListening(); jsonRpc.TraceSource = new TraceSource("ClientTraceSource") { Switch = new SourceSwitch("ClientSourceSwitch", "Verbose") }; jsonRpc.TraceSource.Listeners.Add(new ConsoleTraceListener()); await jsonRpc.Completion.WithCancellation(cancellationToken); }
private async Task RespondToRpcRequestsAsync(Stream stream, int clientId) { Console.WriteLine($"Connection made, clientId = {clientId}"); var cancellationTokenSource = new CancellationTokenSource(); var formatter = new JsonMessageFormatter(Encoding.UTF8); //formatter.ProtocolVersion = new Version(1, 0); var handler = new NewLineDelimitedMessageHandler(stream, stream, formatter) { NewLine = NewLineDelimitedMessageHandler.NewLineStyle.Lf }; var jsonRpc = new JsonRpc(handler); jsonRpc.AddLocalRpcTarget(new Notifications(cancellationTokenSource.Token)); jsonRpc.StartListening(); jsonRpc.TraceSource = new TraceSource("ServerTraceSource") { Switch = new SourceSwitch("ServerSourceSwitch", "Verbose") }; jsonRpc.TraceSource.Listeners.Add(new ConsoleTraceListener()); await jsonRpc.Completion; cancellationTokenSource.Cancel(); Console.WriteLine($"Connection terminated, clientId = {clientId}"); }
public void NewLine() { var handler = new NewLineDelimitedMessageHandler(FullDuplexStream.CreatePipePair().Item1, new JsonMessageFormatter()); // Assert default value. Assert.Equal(NewLineDelimitedMessageHandler.NewLineStyle.CrLf, handler.NewLine); handler.NewLine = NewLineDelimitedMessageHandler.NewLineStyle.Lf; Assert.Equal(NewLineDelimitedMessageHandler.NewLineStyle.Lf, handler.NewLine); }
public async Task Reading_IncompleteLine() { var pipe = new Pipe(); var handler = new NewLineDelimitedMessageHandler(null, pipe.Reader, new JsonMessageFormatter()); var testFormatter = new JsonMessageFormatter(); // Send just the message, but no newline yet. testFormatter.Serialize(pipe.Writer, this.mockMessages[0]); await pipe.Writer.FlushAsync(this.TimeoutToken); // Assert that the handler will wait for more bytes. var readTask = handler.ReadAsync(this.TimeoutToken).AsTask(); await Assert.ThrowsAsync <TimeoutException>(() => readTask.WithTimeout(ExpectedTimeout)); // Now finish with a newline and assert that the message was read. pipe.Writer.Write(testFormatter.Encoding.GetBytes("\r\n")); await pipe.Writer.FlushAsync(this.TimeoutToken); var msg = await readTask.WithCancellation(this.TimeoutToken); Assert.True(msg is JsonRpcRequest); }
static void Main(string[] args) { FileDialogs.Init(); var serverStream = new SimplexStream(); var clientStream = new SimplexStream(); var encoding = new UTF8Encoding(false); var writer = new StreamWriter(serverStream, encoding); var formatter = new JsonMessageFormatter(encoding); Serializer.PrepareSerializer(formatter.JsonSerializer); var messageHandler = new NewLineDelimitedMessageHandler(clientStream, serverStream, formatter); var server = new FullServer(messageHandler); server.Workspace.SettingsService.RegisterSetting(DisplaySettingsNames.Theme, typeof(string), "xp/98.css"); server.Agent.IsReady += (o, e) => { if (args.Length == 1) { var _ = server.Workspace.ExecuteCommand("File.Open", args[0]); } }; // try to load settings string[] settingsLines = Array.Empty <string>(); var settingsFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".bcadconfig"); try { settingsLines = File.ReadAllLines(settingsFilePath); server.Workspace.SettingsService.LoadFromLines(settingsLines); server.Workspace.Update(isDirty: false); } catch { // don't really care if it failed } #if DEBUG var allowDebugging = true; var logVerbosity = 1; var clientArguments = new[] { "--", "debug" }; #else var allowDebugging = false; var logVerbosity = 0; var clientArguments = new[] { "--" }; #endif var window = new PhotinoWindow() .SetUseOsDefaultSize(true) .SetContextMenuEnabled(false) .Center() .SetDevToolsEnabled(allowDebugging) .SetResizable(true) .SetLogVerbosity(logVerbosity) .RegisterWebMessageReceivedHandler((object sender, string message) => { try { // forward JSON from client to server writer.WriteLine(message); writer.Flush(); } catch { // don't let this die } }); SetTitle(window, server.Workspace); window.RegisterCustomSchemeHandler("app", (object sender, string scheme, string url, out string contentType) => { contentType = "text/javascript"; var script = $"var clientArguments = [{string.Join(", ", clientArguments.Select(arg => $"\"{arg}\""))}];"; return(new MemoryStream(Encoding.UTF8.GetBytes(script))); }); var fileSystemService = new FileSystemService(action => { window.Invoke(action); }); server.Workspace.RegisterService(fileSystemService); server.Workspace.WorkspaceChanged += (sender, args) => SetTitle(window, server.Workspace); var doHardClose = false; window.WindowClosing += (sender, args) => { if (doHardClose) { // close immediately return(false); } if (server.Workspace.IsDirty) { var _ = Task.Run(async() => { var result = await server.Workspace.PromptForUnsavedChanges(); if (result != UnsavedChangesResult.Cancel) { doHardClose = true; window.Close(); } }); // don't close yet return(true); } return(false); }; var _ = Task.Run(async() => { var reader = new StreamReader(clientStream, encoding); while (true) { try { var line = await reader.ReadLineAsync(); window.SendWebMessage(line); } catch { // don't let this die } } }); server.Start(); var indexPath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "index.html"); window.Load(indexPath); window.WaitForClose(); // try to save settings try { var newSettingsContents = server.Workspace.SettingsService.WriteWithLines(settingsLines); File.WriteAllText(settingsFilePath, newSettingsContents); } catch { // don't really care if it failed } }