Skip to content

Debug protocol: Support browser launching #23

Description

Currently the debug protocol has no way for a debug adapter to request that the IDE open up a web browser. Some debug adapters, such as the C# debug adapter, can start a web browser as part of launching a web server project. The debug adapter needs some control to be able to signal when the web server is ready.

This could either be designed as an event (ex: WebServerReady) or as a callback request like starting processes in the terminal.

Dependent issue: dotnet/vscode-csharp#2657
Related issue: microsoft/vscode-debugadapter-node#153

Activity

  1. changed the title [-]Support browser launching in the protocol[/-] [+]Debug protocol: Support browser launching[/+] on Nov 28, 2018
  2. weinand commented on Feb 12, 2019

    @weinand
    Contributor

    Proposal:

    If a client (frontend) supports the 'openExternal' request, it must announce this by setting the supportsOpenExternalRequest in the 'initialize' request to true:

    /** Arguments for 'initialize' request. */
    export interface InitializeRequestArguments {
    
    	// ...
    	
    	/** Client supports the openExternal request. */
    	supportsOpenExternalRequest?: boolean;
    }

    And a debug adapter can then use the 'openExternal' request by passing the uri as the only (mandatory) argument:

    /** OpenExternal request; value of command field is 'openExternal'.
    	This request is sent from the debug adapter to the client to open a url in an external program, e.g. a http(s) or mailto-link, using the default application.
    */
    export interface OpenExternalRequest extends Request {
    	// command: 'openExternal';
    	arguments: OpenExternalArguments;
    }
    
    /** Arguments for 'openExternal' request. */
    export interface OpenExternalArguments {
    	/** The uri that should be opened. */
    	url: string;
    }
    
    /** Response to 'openExternal' request. This is just an acknowledgement, so no body field is required. */
    export interface OpenExternalResponse extends Response {
    }
  3. weinand commented on Feb 12, 2019

    @weinand
    Contributor

    Gregg Miskelly (@gregg-miskelly) Andrew Crawley (@andrewcrawley) Chuck Ries (@chuckries) Don Jayamanne (@DonJayamanne) Pierson Lee (@pieandcakes)
    You can find my proposal for a openExternal request in the branch;

    For your convenience I've added the corresponding TypeScript definitions above.

    I'd appreciate any feedback.

  4. DonJayamanne commented on Feb 12, 2019

    @DonJayamanne

    Sounds, good, however wouldn't a custom request also solve this.
    Send a custom request from debug adapter, and handle that from the extension to launch the browser?
    Just trying to understand use causes for custom requests.

  5. weinand commented on Feb 12, 2019

    @weinand
    Contributor

    Yes, a custom request picked up in the corresponding extension could do the same. However, including this new request in the DAP simplifies the case where debug adapters are hosted by a different client than VS Code.

  6. auchenberg commented on Feb 12, 2019

    @auchenberg

    One aspect we should think about here, is how this potentially could play together with other debug adaptors in VS Code?

    A typical scenario for ASP.Net developers is
    0) Press F5 / Launch

    1. Launch asp.net server-side
    2. Launch Chrome in debug mode
    3. Attach VS code to .net
    4. Attach VS Code to Chrome
      = debug both stacks at the same time.

    Ideas: In the .net DA, for the OpenExternalRequest handler instead of having it's own browser logic, maybe it could try to start a browser debugging session for Chrome/Edge/Firefox?

    If no debugging is wished, fallback to new vscode.openExternal api?

  7. weinand commented on Feb 12, 2019

    @weinand
    Contributor

    Kenneth Auchenberg (@auchenberg) multi-debugger cases like your scenario are best handled in an extension since a debug adapter has no access to VS Code's extension API (and cannot assume that it runs in VS Code at all).

    The openExternal request is for the scenario from Gregg Miskelly (@gregg-miskelly)'s initial comment or maybe for "The debugger for Chrome".

    roblourens and Gregg Miskelly (@gregg-miskelly) please chime in for additional thoughts...

  8. gregg-miskelly commented on Feb 12, 2019

    @gregg-miskelly
    MemberAuthor

    I didn't see any changes in your branch, but the type script definitions above look good to me.

  9. weinand commented on Feb 12, 2019

    @weinand
    Contributor

    Gregg Miskelly (@gregg-miskelly) sorry, I forgot to push. The commit is ac0289e

  10. gregg-miskelly commented on Feb 14, 2019

    @gregg-miskelly
    MemberAuthor

    LGTM

  11. roblourens commented on Feb 14, 2019

    @roblourens
    Member

    The original scenario is that your C# app is running a server and you want to launch a browser to see the page. If someone wants to debug the page in vscode, this doesn't help with that. For that we would need a way for the chrome debug extension to know when the server is ready and what the url is. Or the C# extension could generate a chrome launch config and start it.

    Are you also thinking about that scenario? If that's not what you're focusing on right now this is fine for just launching the system's default app for some uri.

  12. 22 remaining items

  13. weinand commented on Feb 20, 2019

    @weinand
    Contributor

    Ben Jackson (@puremourning) "runInTerminal" is a request because the DA relies on it to launch a target. If "runInTerminal" fails, launching a target fails. The "runInTerminal" spec is a "must".

    "serverReady" is an event because it does not require anything from a client. Events don't fail and they don't return a result. Events are used for loose coupling. The "serverReady" spec would be a "might" (like all event specs).

    If a headless DAP client decides to not handle "serverReady" because it does not have a browser, then that's perfectly fine and the spec should make this clear.

    Eliminating "could" and "shoulds" from a spec like DAP doesn't make sense, because the protocol spec neither covers the functionality or scope of a client (frontend), nor the functionality or scope of the DA (backend).

  14. weinand commented on Feb 20, 2019

    @weinand
    Contributor

    The "Server Ready" extension mentioned above is now available for Insiders here: https://marketplace.visualstudio.com/items?itemName=andreweinand.server-ready

    It does not require any new DAP features and works with all existing debugger extensions (as long as they use DAP "output" events for sending output to the debug console).

  15. puremourning commented on Feb 20, 2019

    @puremourning
    Contributor

    Ok thanks for the explanation. :)

  16. gregg-miskelly commented on Feb 20, 2019

    @gregg-miskelly
    MemberAuthor

    Detecting when ASP.NET is ready

    Gregg Miskelly (@gregg-miskelly) how would you implement the serverReady event in the C# debug adapter? Do you have a better way than scanning the output?

    The C# debugger currently is also just scrapping stdout. We look for lines that start with 'Now listening on '. If we want to avoid adding the new serverReady event, here are the special things that ASP.NET Core does (that I am aware of at least) --

    1. [::] can be the host name for the any IP address. When we see this we convert it to 'localhost'. We actually currently convert anything which isn't an IP Address to localhost. So people may be relying on some other conversions as well.
    2. There are normally multiple 'Now listening on:' lines as the default is configured to listen on both https and http. We only pay attention to the first one.

    Server-ready extension

    I would be fine with replacing our current browser launch code either with something that raised the serverReady event, or updating our launch.json templates to output the right json to light up link detection in the server-ready extension. However, we would need either the extension to ship in-box, or for there to be a good way to advertise to users that they should install the server-ready extension. Example 'advertise' solutions: the C# extension could call an API to add the recommendation, or VS Code could add the recommendation if a workspace had a launch.json file which used serverReadyAction.

    For reference, here is the output from starting a 'hello world' ASP.NET Core app --

    > dotnet run
    info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
          User profile is available. Using 'C:\Users\greggm\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
    Hosting environment: Development
    Content root path: C:\proj\climvc
    Now listening on: https://localhost:5001
    Now listening on: http://localhost:5000
    Application started. Press Ctrl+C to shut down.
    
  17. auchenberg commented on Feb 20, 2019

    @auchenberg

    Playing devils advocate here Gregg Miskelly (@gregg-miskelly): If you already are listening to the process output, why can't your VS Code extension that wraps the Debug Adaptor, just call vscode.env.openExternal(vscode.Uri.parse(uri)); directly? It would be an implementation detail in between your Debug Adaptor and VS Code extension.

  18. gregg-miskelly commented on Feb 20, 2019

    @gregg-miskelly
    MemberAuthor

    Kenneth Auchenberg (@auchenberg) personally that feels like a hack to me. There are lots of programming languages that are popular for creating web servers. If we expect folks will want to use a VS Code API to start a web browser then we shouldn't make every language tie their debug adapter to VS Code to do so.

  19. weinand commented on Feb 21, 2019

    @weinand
    Contributor

    We propose the following:

    • we ship the "server-ready" functionality as a built-in extension (most likely as a part of the existing "debug-auto-launch" extension which I will rename to "debug-features"). This makes the functionality appear as built-into VS Code.
    • We will obey Gregg's implementation details from above Debug protocol: Support browser launching #23 (comment)
    • In February we will ship this feature as a "Preview". This makes it possible to tweak naming and functionality in the March release.
  20. DonJayamanne commented on Feb 21, 2019

    @DonJayamanne

    Looking forward to this

  21. roblourens commented on Feb 21, 2019

    @roblourens
    Member

    This is a really interesting use of the debug adapter tracker API! It could technically be used for other things besides waiting for a server to be ready so I wonder if we would want to generalize the naming of it beyond "server ready". Could call it a "launch config trigger" or something like that.

    For example, when I debug vscode, I sometimes want to attach to the search process, but it doesn't start until some time after vscode starts, so a normal compound config doesn't work. I could write to the console when it starts, and set up a node attach config to trigger when that output is detected.

  22. weinand commented on Feb 22, 2019

    @weinand
    Contributor

    roblourens glad you liked it ;-)
    Your use cases make perfect sense and we can start to support them (and rename things) next milestone. For the February release we want to ship a "preview" of the feature to gather feedback.

    The next Insider build (Monday) will have the serverReadyAction support (and I've unpublished the "Server Ready" extension from the Marketplace to avoid confusion...)

  23. weinand commented on Feb 24, 2019

    @weinand
    Contributor

    I've create a new feature microsoft/vscode#69311 for February to cover the built-in extension created for this.

  24. weinand commented on Mar 1, 2019

    @weinand
    Contributor

    I'm closing this request for a DAP addition because we could address the need by a client/frontend implementation (microsoft/vscode#69311).

  25. locked and limited conversation to collaborators on Apr 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions