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));
    }
예제 #3
0
        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);
        }
예제 #4
0
        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);
    }
예제 #7
0
파일: Program.cs 프로젝트: ixmilia/bcad
        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
            }
        }