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

Use websocket /message endpoint to deliver reload request #667

Merged
merged 3 commits into from
Oct 30, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions packages/vscode-extension/src/project/metro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,28 +267,35 @@ export class Metro implements Disposable {
return initPromise;
}

public async reload() {
const appReady = this.devtools.appReady();
await fetch(`http://localhost:${this._port}/reload`);
await appReady;
}

public async openDevMenu() {
// to send request to open dev menu, we route it through metro process
// that maintains a websocket connection with the device. Specifically,
// /message endpoint is used to send messages to the device, and metro proxies
// messages between different clients connected to that endpoint.
// Therefore, to send the message to the device we:
// 1. connect to the /message endpoint over websocket
// 2. send specifically formatted message to open dev menu
private async sendMessageToDevice(message: "devMenu" | "reload") {
kmagiera marked this conversation as resolved.
Show resolved Hide resolved
// we use metro's /message websocket endpoint to deliver specifically formatted
// messages to the device.
// Metro implements a websocket proxy that proxies messages between connected
// clients. This is a mechanism used by the CLI to deliver messages for things
// like reload or open dev menu.
// The message format is a JSON object with a "method" field that specifies
// the action, and version field with the protocol version (currently 2).
const ws = new WebSocket(`ws://localhost:${this._port}/message`);
await new Promise((resolve) => ws.addEventListener("open", resolve));
ws.send(
JSON.stringify({ version: 2 /* protocol version, needs to be set to 2 */, method: "devMenu" })
JSON.stringify({
version: 2 /* protocol version, needs to be set to 2 */,
method: message,
kmagiera marked this conversation as resolved.
Show resolved Hide resolved
})
);
// we disconnect immediately after sending the message as there's no need
// to keep the connection open since we use it on rare occations.
ws.close();
}

public async reload() {
await this.sendMessageToDevice("reload");
}

public async openDevMenu() {
await this.sendMessageToDevice("devMenu");
}

public async getDebuggerURL() {
const WAIT_FOR_DEBUGGER_TIMEOUT_MS = 15_000;

Expand Down