Skip to content

Support connecting to VM service via MessagePort / postMessage - #9964

Open
jonasfj wants to merge 2 commits into
flutter:masterfrom
jonasfj:devtools_iframe_messageport_integration
Open

jonasfj wants to merge 2 commits into
flutter:masterfrom
jonasfj:devtools_iframe_messageport_integration

Conversation

@jonasfj

@jonasfj jonasfj commented Aug 18, 2026 •

Copy link
Copy Markdown
Member

Support for providing VM service protocol using a MessagePort.

  • ?uri=messageport:<targetOrigin>
  • devtools will do window.parent.postMessage({action: 'connect', port})

Then parent window is responsible for proxying messages into the MessagePort.

Note: MessagePort doesn't actually carry a disconnect / closed event, so in an ideal world we might want to allow the other end to send null to indicate end-of-stream. But I'm not sure we need it.

For context I'm trying to add the VM Service Protocol bits required in package:dartpad here: sdk/+/554920

AI description

Adds ?uri=messageport:<targetOrigin>, so a page embedding DevTools can provide the VM service connection over a MessagePort instead of a WebSocket URI.

  • Why: DartPad runs its VM service in a web worker, so there is no WebSocket for DevTools to connect to.
  • Protocol: on every connect, including reconnects and reloads, DevTools creates a MessageChannel and posts one port to the embedding page:
    window.parent.postMessage({action: 'connect', port}, targetOrigin, [port]);
    The embedding page connects the port to a VM service. Messages are JSON-RPC strings, or binary frames as Uint8Array. Only the latest port is used.
  • Design: a URI scheme rather than a new query parameter, so routing, reconnecting and reloading keep working unchanged. The transport lives in devtools_app rather than in devtools_shared's connect, because that is published API and must not depend on web-only libraries.
  • Not supported yet: DevTools extensions receive the messageport: URI but can't connect with it.
  • Tests: VM tests for URI handling and the non-web stub, plus a browser test that plays both the embedding page and a fake VM service. CI only runs devtools_app tests on the VM, so I ran the browser test locally with --platform chrome and --platform chrome --wasm.

@kenzieschmoll

Copy link
Copy Markdown
Member

CC @bkonyi

Adds `?uri=messageport:<targetOrigin>`. On every connect, DevTools posts
a new `MessagePort` to `window.parent`, and the embedding page connects
it to a VM service. This lets pages such as DartPad, whose VM service
runs in a web worker, embed DevTools without a WebSocket.
@jonasfj
jonasfj force-pushed the devtools_iframe_messageport_integration branch from 4585928 to 1f9592c Compare September 28, 2026 20:05
@jonasfj
jonasfj marked this pull request as ready for review September 28, 2026 20:40
@jonasfj
jonasfj requested a review from a team as a code owner September 28, 2026 20:40
@jonasfj
jonasfj requested review from srawlins and removed request for a team September 28, 2026 20:40

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for proxying the VM service connection over a MessagePort, allowing DevTools to connect when embedded in an iframe. The implementation includes a web-specific connection handler, a stub for other platforms, and corresponding tests. The review feedback identifies several areas for improvement: adding a check for window.parent to prevent hanging when not embedded, implementing a graceful disconnection mechanism via null signals, validating the URI path to avoid runtime exceptions, and adding a timeout to the connection verification process to ensure robustness.

Comment thread packages/devtools_app/lib/src/service/_message_port_connection_web.dart Outdated

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants