From fa7bd3dda81718a5ad668f45afaf159ea3d703c3 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 25 Mar 2025 15:44:46 +0100 Subject: [PATCH 1/5] rebase --- .../WebSocketServerImpl.cs | 22 +++++++++---------- src/Tools/dotnet-dsrouter/Program.cs | 3 ++- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.Diagnostics.WebSocketServer/WebSocketServerImpl.cs b/src/Microsoft.Diagnostics.WebSocketServer/WebSocketServerImpl.cs index f34e5907ce..5d7b821ba3 100644 --- a/src/Microsoft.Diagnostics.WebSocketServer/WebSocketServerImpl.cs +++ b/src/Microsoft.Diagnostics.WebSocketServer/WebSocketServerImpl.cs @@ -172,24 +172,24 @@ private static void ParseWebSocketURL(string endPoint, out Uri uri) uriToParse = endPoint; } - string[] supportedSchemes = new string[] { "ws", "wss", "http", "https" }; if (!string.IsNullOrEmpty(uriToParse) && Uri.TryCreate(uriToParse, UriKind.Absolute, out uri)) { - bool supported = false; - foreach (string scheme in supportedSchemes) + if (uri.Scheme == "ws") { - if (string.Equals(uri.Scheme, scheme, StringComparison.InvariantCultureIgnoreCase)) - { - supported = true; - break; - } + uri = new UriBuilder(uri) { Scheme = "http" }.Uri; + return; } - if (!supported) + if (uri.Scheme == "wss") { - throw new ArgumentException(string.Format("Unsupported Uri schema, \"{0}\"", uri.Scheme)); + uri = new UriBuilder(uri) { Scheme = "https" }.Uri; + return; } - return; + if (uri.Scheme == "http" || uri.Scheme == "https") + { + return; + } + throw new ArgumentException(string.Format("Unsupported Uri schema, \"{0}\"", uri.Scheme)); } else { diff --git a/src/Tools/dotnet-dsrouter/Program.cs b/src/Tools/dotnet-dsrouter/Program.cs index 253ad35b4a..27b347c053 100644 --- a/src/Tools/dotnet-dsrouter/Program.cs +++ b/src/Tools/dotnet-dsrouter/Program.cs @@ -267,7 +267,8 @@ private static Command AndroidRouterCommand() new("--web-socket", "-ws") { Description = "The router WebSocket address using format ws://[host]:[port]/[path] or wss://[host]:[port]/[path]. " + - "Launch app with WasmExtraConfig property specifying diagnostic_options with a server connect_url" + "Launch app with WasmExtraConfig property specifying diagnostic_options with a server connect_url", + DefaultValueFactory = _ => "ws://127.0.0.1:8088/diagnostics" }; private static readonly Option RuntimeTimeoutOption = From f1797a4b9c036ba603d385f0ef74c913e91468cb Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 25 Mar 2025 16:17:29 +0100 Subject: [PATCH 2/5] longer timeout for the browser WS --- .../ReversedServer/ReversedDiagnosticsServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs b/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs index b0ea799412..b0b222e1de 100644 --- a/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs +++ b/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs @@ -21,7 +21,7 @@ internal sealed class ReversedDiagnosticsServer : IAsyncDisposable { // The amount of time to allow parsing of the advertise data before cancelling. This allows the server to // remain responsive in case the advertise data is incomplete and the stream is not closed. - private static readonly TimeSpan ParseAdvertiseTimeout = TimeSpan.FromMilliseconds(250); + private static readonly TimeSpan ParseAdvertiseTimeout = TimeSpan.FromMilliseconds(750); private readonly CancellationTokenSource _disposalSource = new(); private readonly HandleableCollection _endpointInfos = new(); From 8e52e38d3512d142d1e025e1ccce443f39882e80 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Thu, 27 Mar 2025 11:15:50 +0100 Subject: [PATCH 3/5] feedback --- .../DiagnosticsServerRouterFactory.cs | 6 ++-- .../ReversedDiagnosticsServer.cs | 31 +++++++++++++++++-- src/Tools/dotnet-dsrouter/Program.cs | 4 +-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsServerRouter/DiagnosticsServerRouterFactory.cs b/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsServerRouter/DiagnosticsServerRouterFactory.cs index c79bd3c15e..e7287c0fd9 100644 --- a/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsServerRouter/DiagnosticsServerRouterFactory.cs +++ b/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsServerRouter/DiagnosticsServerRouterFactory.cs @@ -356,9 +356,11 @@ public static WebSocketServerRouterFactory CreateDefaultInstance(string webSocke public WebSocketServerRouterFactory(string webSocketURL, int runtimeTimeoutMs, ILogger logger) : base(runtimeTimeoutMs, logger) { - _webSocketURL = string.IsNullOrEmpty(webSocketURL) ? "ws://127.0.0.1:8088/diagnostics" : webSocketURL; + Debug.Assert(!string.IsNullOrEmpty(webSocketURL)); - _webSocketServer = new ReversedDiagnosticsServer(_webSocketURL, ReversedDiagnosticsServer.Kind.WebSocket); + _webSocketURL = webSocketURL; + + _webSocketServer = new ReversedDiagnosticsServer(_webSocketURL, ReversedDiagnosticsServer.Kind.WebSocket, TimeSpan.FromMilliseconds(750)); _webSocketServer.TransportCallback = this; } diff --git a/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs b/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs index b0b222e1de..ebdc949e43 100644 --- a/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs +++ b/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs @@ -21,7 +21,7 @@ internal sealed class ReversedDiagnosticsServer : IAsyncDisposable { // The amount of time to allow parsing of the advertise data before cancelling. This allows the server to // remain responsive in case the advertise data is incomplete and the stream is not closed. - private static readonly TimeSpan ParseAdvertiseTimeout = TimeSpan.FromMilliseconds(750); + private readonly TimeSpan ParseAdvertiseTimeout; private readonly CancellationTokenSource _disposalSource = new(); private readonly HandleableCollection _endpointInfos = new(); @@ -52,6 +52,7 @@ public enum Kind public ReversedDiagnosticsServer(string address) { _address = address; + ParseAdvertiseTimeout = TimeSpan.FromMilliseconds(750); } /// @@ -69,12 +70,38 @@ public ReversedDiagnosticsServer(string address) /// Otherwise if kind is TcpIp as a supported protocol for ReversedDiagnosticServer. When Kind is Tcp, address will /// be analyzed and if on format host:port, ReversedDiagnosticServer will try to bind /// a TcpIp listener to host and port, otherwise it will use a Unix domain socket or a Windows named pipe. - /// /// public ReversedDiagnosticsServer(string address, Kind kind) { _address = address; _kind = kind; + ParseAdvertiseTimeout = TimeSpan.FromMilliseconds(750); + } + + /// + /// Constructs the instance with an endpoint bound + /// to the location specified by . + /// + /// + /// The server endpoint. + /// On Windows, this can be a full pipe path or the name without the "\\.\pipe\" prefix. + /// On all other systems, this must be the full file path of the socket. + /// + /// + /// If kind is WebSocket, start a Kestrel web server. + /// Otherwise if kind is TcpIp as a supported protocol for ReversedDiagnosticServer. When Kind is Tcp, address will + /// be analyzed and if on format host:port, ReversedDiagnosticServer will try to bind + /// a TcpIp listener to host and port, otherwise it will use a Unix domain socket or a Windows named pipe. + /// + /// + /// The amount of time to allow parsing of the advertise data before cancelling. This allows the server to + /// remain responsive in case the advertise data is incomplete and the stream is not closed. + /// + public ReversedDiagnosticsServer(string address, Kind kind, TimeSpan timeout) + { + _address = address; + _kind = kind; + ParseAdvertiseTimeout = timeout; } public async ValueTask DisposeAsync() diff --git a/src/Tools/dotnet-dsrouter/Program.cs b/src/Tools/dotnet-dsrouter/Program.cs index 27b347c053..b5cd886ab7 100644 --- a/src/Tools/dotnet-dsrouter/Program.cs +++ b/src/Tools/dotnet-dsrouter/Program.cs @@ -95,7 +95,7 @@ private static Command IpcServerWebSocketServerRouterCommand() command.SetAction((parseResult, ct) => new DiagnosticsServerRouterCommands().RunIpcServerWebSocketServerRouter( ct, ipcServer: parseResult.GetValue(IpcServerAddressOption) ?? "", - webSocket: parseResult.GetValue(WebSocketURLAddressOption) ?? "", + webSocket: parseResult.GetValue(WebSocketURLAddressOption), runtimeTimeout: parseResult.GetValue(RuntimeTimeoutOption), verbose: parseResult.GetValue(VerboseOption) )); @@ -117,7 +117,7 @@ private static Command IpcClientWebSocketServerRouterCommand() command.SetAction((parseResult, ct) => new DiagnosticsServerRouterCommands().RunIpcClientWebSocketServerRouter( ct, ipcClient: parseResult.GetValue(IpcClientAddressOption) ?? "", - webSocket: parseResult.GetValue(WebSocketURLAddressOption) ?? "", + webSocket: parseResult.GetValue(WebSocketURLAddressOption), runtimeTimeout: parseResult.GetValue(RuntimeTimeoutOption), verbose: parseResult.GetValue(VerboseOption) )); From 51d458c85368654907c0a50caf13e1ec3f47b2d2 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Thu, 27 Mar 2025 12:07:05 +0100 Subject: [PATCH 4/5] feedback --- .../ReversedServer/ReversedDiagnosticsServer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs b/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs index ebdc949e43..72c690c49e 100644 --- a/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs +++ b/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer/ReversedDiagnosticsServer.cs @@ -52,7 +52,7 @@ public enum Kind public ReversedDiagnosticsServer(string address) { _address = address; - ParseAdvertiseTimeout = TimeSpan.FromMilliseconds(750); + ParseAdvertiseTimeout = TimeSpan.FromMilliseconds(250); } /// @@ -75,7 +75,7 @@ public ReversedDiagnosticsServer(string address, Kind kind) { _address = address; _kind = kind; - ParseAdvertiseTimeout = TimeSpan.FromMilliseconds(750); + ParseAdvertiseTimeout = TimeSpan.FromMilliseconds(250); } /// From cb73c323ebe331cb060f912f0ec5b26a9a181c6f Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Thu, 27 Mar 2025 16:49:22 +0100 Subject: [PATCH 5/5] feedback --- .../WebSocketServerImpl.cs | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.Diagnostics.WebSocketServer/WebSocketServerImpl.cs b/src/Microsoft.Diagnostics.WebSocketServer/WebSocketServerImpl.cs index 5d7b821ba3..e7e53cf986 100644 --- a/src/Microsoft.Diagnostics.WebSocketServer/WebSocketServerImpl.cs +++ b/src/Microsoft.Diagnostics.WebSocketServer/WebSocketServerImpl.cs @@ -40,9 +40,18 @@ public async Task StartServer(string endpoint, CancellationToken cancellationTok ParseWebSocketURL(endpoint, out Uri uri); + string scheme = uri.Scheme switch + { + "ws" => "http", + "http" => "http", + "wss" => "https", + "https" => "https", + _ => throw new ArgumentException(string.Format("Unsupported Uri schema, \"{0}\"", uri.Scheme)) + }; + EmbeddedWebSocketServer.Options options = new() { - Scheme = uri.Scheme, + Scheme = scheme, Host = uri.Host, Port = uri.Port.ToString(), Path = uri.PathAndQuery, @@ -172,24 +181,24 @@ private static void ParseWebSocketURL(string endPoint, out Uri uri) uriToParse = endPoint; } + string[] supportedSchemes = new string[] { "ws", "wss", "http", "https" }; if (!string.IsNullOrEmpty(uriToParse) && Uri.TryCreate(uriToParse, UriKind.Absolute, out uri)) { - if (uri.Scheme == "ws") - { - uri = new UriBuilder(uri) { Scheme = "http" }.Uri; - return; - } - if (uri.Scheme == "wss") + bool supported = false; + foreach (string scheme in supportedSchemes) { - uri = new UriBuilder(uri) { Scheme = "https" }.Uri; - return; + if (string.Equals(uri.Scheme, scheme, StringComparison.InvariantCultureIgnoreCase)) + { + supported = true; + break; + } } - if (uri.Scheme == "http" || uri.Scheme == "https") + if (!supported) { - return; + throw new ArgumentException(string.Format("Unsupported Uri schema, \"{0}\"", uri.Scheme)); } - throw new ArgumentException(string.Format("Unsupported Uri schema, \"{0}\"", uri.Scheme)); + return; } else {