Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add websocket modes to dotnet-dsrouter #3461

Merged
merged 30 commits into from
Nov 15, 2022
Merged

Conversation

lambdageek
Copy link
Member

@lambdageek lambdageek commented Oct 13, 2022

In .NET 8, the .NET runtime may ship a variant of the WebAssembly runtime that supports diagnostic tracing (this is an optional opt-in because it requires threading support, which is opt-in). Runtime tracking issue: dotnet/runtime#69268

In order to support tracing in WebAssembly apps, the dotnet-dsrouter tool needs a new mode where it can create a WebSocket server that will allow a .NET app running in the browser to connect to it.

$ dotnet-dsrouter server-websocket -ipcs ./domain_socket -ws ws://localhost:12345/diagnostics

After that, the usual diagnostics commands such as dotnet-trace will be able to collect diagnostics from running WebAssembly apps.

$ dotnet-trace collect --diagnostic-port ./domain_socket,connect ...

All the remaining work is done or pushed off to the next PR

  • done cleanup rogue Console.WriteLines from the initial development
  • done thread ILoggerFactory through from dotnet-dsrouter down to WebSocketServer (through the diagnostic client library) to allow Kestrel to log at the same levels as the rest of the tool. pass logging level through to the generic host builder
  • out of scope Spinning out the websocket handling into a DI middleware - in some scenarios we actually want to load it into an existing server (browsers don't always allow you to connect to arbitrary websocket url's if oyu're not deployed on localhost) Will make the library suitable for the wasm dev server in a future PR
  • done Find a better way to instantiate the WebSocketServer than by setting an environment variable and using Activator.CreateInstance the client library already has IVT for dotnet-dsrouter, so we can just use an internal singleton to set a webserver factory.

Questions:

  • Should we consider targeting netcoreapp3.1 instead of net6? The issue that all the DI stuff for setting up the generic host and starting Kestrel is different for .NET Core 3.1 and .NET 6. Only dotnet-dsrouter is changing, all the other libraries are still 3.1.

Fixes #3422

@lambdageek
Copy link
Member Author

@lateralusX Could you take a look. Not a detailed review yet, but maybe your high-level impression.

Copy link
Member Author

@lambdageek lambdageek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copy/pasted a bunch of code, based on what the Tcp and Icp transports do. But this could probably do with some abstract base classes that provide shared behavior.

Somehow the abstractions aren't a good fit for where the code actuall differs.

@lambdageek lambdageek changed the title [DRAFT] add server-websocket mode to dotnet-dsrouter [DRAFT] add websocket modes to dotnet-dsrouter Oct 19, 2022
@lambdageek lambdageek marked this pull request as ready for review October 20, 2022 13:03
@lambdageek lambdageek requested a review from a team as a code owner October 20, 2022 13:03
@lambdageek
Copy link
Member Author

@lateralusX @dotnet/dotnet-diag I think this ready for a review now

@lambdageek lambdageek changed the title [DRAFT] add websocket modes to dotnet-dsrouter Add websocket modes to dotnet-dsrouter Oct 20, 2022
lambdageek and others added 19 commits October 26, 2022 13:31
add an interface for it in the Client library, and expose a way to
check that it's conncted.
Use IpcServerTcpServerRouterFactory since everything is sufficiently abstracted
In this mode the tracing command will start a domain socket and the
runtime will connect to it:

```
dotnet trace collect --diagnostic-port /tmp/sock
```

Then

```
dotnet run --project src/Tools/dotnet-dsrouter -- client-websocket -ipcc /tmp/sock -ws http://localhost:8088/diagnostics
```

And finally launch the app in the browser http://localhost:8000 (or
whatever you configured)

In this mode, the app should be configured without suspending on
startup
```
    <WasmExtraConfig Include="environmentVariables" Value='
{
  "DOTNET_DiagnosticPorts": "ws://localhost:8088/diagnostics",
}' />
```
it was just encapsulating a single URL parser call.
rename the class that encapsulated IHost and the embedded Kestrel
instance to EmbeddedWebServer

add comments explaining the various pieces
and IVT for Microsoft.Diagnostics.WebSocketServer that holds the implementation
Copy link
Member

@lateralusX lateralusX left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Nice work on the refactoring and code reuse aspects as well. Mainly some whitespace nits, and a couple of questions/comments coming to mind when reading through the code.

There are plans to upgrade dotnet tools/components to .net6 soon, but so far all are still on 3.1, made comments that these projects should probably follow the rest of the tools and components and build using 3.1 and upgraded once all tools/components move up to .net6, unless that is a major issue.

Small reflection on the name NetServerRouterFactory, maybe an alternative could have been SocketServerRouterFactory and then we could have TcpSocketServer, WebSocketServer, TcpSocketClient through the code, but that is just naming, if you don't agree we could stick with NetServerRouterFactory and/or change it at some later point in time.

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this needs to be insync with rest of diagnostic repro, the plan was to bump, but not sure that has happened yet over the board.

src/Tools/dotnet-dsrouter/Program.cs Outdated Show resolved Hide resolved
@lateralusX
Copy link
Member

Btw, did you take changed dsrouter on a test ride against the regular tcp backend as well?

@lambdageek
Copy link
Member Author

Btw, did you take changed dsrouter on a test ride against the regular tcp backend as well?

no. I'll be sure to try it after I fix the webserver lifetime.

Thanks for the review!

lambdageek and others added 3 commits October 28, 2022 12:54
Co-authored-by: Johan Lorensson <lateralusx.github@gmail.com>
Instead of trying to start the webserver when the diagnostics code first calls
AcceptConnection,
just start the webserver when we start running,
and stop it when the router is done.

This also matches the expected use by WasmAppHost (`dotnet run`) which will
start/stop the webserver itself, and we will
just provide middleware for diagnostics
@lateralusX
Copy link
Member

lateralusX commented Nov 14, 2022

@lambdageek Where you able to verify that things still works using the TCP backend after the change? If so, I believe this PR is good to go.

@lambdageek
Copy link
Member Author

ok, confirmed dotnet-dsrouter server-server from this PR still works with Android. I did not break tcp server mode 😁

@lateralusX lateralusX self-requested a review November 14, 2022 16:46
Copy link
Member

@lateralusX lateralusX left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@lateralusX
Copy link
Member

@tommcdon We need a sign off from dotnet/dotnet-diag before this PR can be merged.

Copy link
Member

@hoyosjs hoyosjs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RE: .NET 6 - the only thing will be that it differs a bit from the expectation that the other tools have, so a bit rougher UX. Otherwise, I can't see anything where this would matter release-wise. We need to move to 6 anyway for the rest of the tools.

Mostly approving so you can merge - I didn't read too closely as I'm not really familiar with all the semantics for this.

src/Tools/dotnet-dsrouter/dotnet-dsrouter.csproj Outdated Show resolved Hide resolved
@lambdageek
Copy link
Member Author

@hoyosjs @lateralusX I'm not authorized to merge in this repo, could one of you do it

@hoyosjs hoyosjs merged commit dd56ba1 into dotnet:main Nov 15, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Jan 11, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[dsrouter] Implement a WebSocket server
4 participants