mirror of
https://github.com/microsoft/playwright-mcp.git
synced 2025-07-27 17:22:27 +08:00
chore(extension): reject second http connection (#766)
This commit is contained in:
parent
6710a78641
commit
dbf113d5e4
@ -69,6 +69,7 @@ class ConnectPage {
|
|||||||
|
|
||||||
continueBtn.addEventListener('click', async () => {
|
continueBtn.addEventListener('click', async () => {
|
||||||
buttonRow.style.display = 'none';
|
buttonRow.style.display = 'none';
|
||||||
|
this._tabListContainer.style.display = 'none';
|
||||||
try {
|
try {
|
||||||
const selectedTab = this._selectedTab;
|
const selectedTab = this._selectedTab;
|
||||||
if (!selectedTab) {
|
if (!selectedTab) {
|
||||||
|
@ -30,6 +30,8 @@ import type { Tool } from './tools/tool.js';
|
|||||||
export class BrowserServerBackend implements ServerBackend {
|
export class BrowserServerBackend implements ServerBackend {
|
||||||
name = 'Playwright';
|
name = 'Playwright';
|
||||||
version = packageJSON.version;
|
version = packageJSON.version;
|
||||||
|
onclose?: () => void;
|
||||||
|
|
||||||
private _tools: Tool[];
|
private _tools: Tool[];
|
||||||
private _context: Context;
|
private _context: Context;
|
||||||
private _sessionLog: SessionLog | undefined;
|
private _sessionLog: SessionLog | undefined;
|
||||||
@ -61,6 +63,7 @@ export class BrowserServerBackend implements ServerBackend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
serverClosed() {
|
serverClosed() {
|
||||||
|
this.onclose?.();
|
||||||
void this._context.dispose().catch(logUnhandledError);
|
void this._context.dispose().catch(logUnhandledError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,8 +123,13 @@ export class CDPRelayServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stop(): void {
|
stop(): void {
|
||||||
this._closePlaywrightConnection('Server stopped');
|
this.closeConnections('Server stopped');
|
||||||
this._closeExtensionConnection('Server stopped');
|
this._wss.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
closeConnections(reason: string) {
|
||||||
|
this._closePlaywrightConnection(reason);
|
||||||
|
this._closeExtensionConnection(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onConnection(ws: WebSocket, request: http.IncomingMessage): void {
|
private _onConnection(ws: WebSocket, request: http.IncomingMessage): void {
|
||||||
@ -141,6 +146,11 @@ export class CDPRelayServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _handlePlaywrightConnection(ws: WebSocket): void {
|
private _handlePlaywrightConnection(ws: WebSocket): void {
|
||||||
|
if (this._playwrightConnection) {
|
||||||
|
debugLogger('Rejecting second Playwright connection');
|
||||||
|
ws.close(1000, 'Another CDP client already connected');
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._playwrightConnection = ws;
|
this._playwrightConnection = ws;
|
||||||
ws.on('message', async data => {
|
ws.on('message', async data => {
|
||||||
try {
|
try {
|
||||||
@ -311,6 +321,11 @@ class ExtensionContextFactory implements BrowserContextFactory {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clientDisconnected() {
|
||||||
|
this._relay.closeConnections('MCP client disconnected');
|
||||||
|
this._browserPromise = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
private async _obtainBrowser(clientInfo: { name: string, version: string }): Promise<playwright.Browser> {
|
private async _obtainBrowser(clientInfo: { name: string, version: string }): Promise<playwright.Browser> {
|
||||||
await this._relay.ensureExtensionConnectionForMCPContext(clientInfo);
|
await this._relay.ensureExtensionConnectionForMCPContext(clientInfo);
|
||||||
const browser = await playwright.chromium.connectOverCDP(this._relay.cdpEndpoint());
|
const browser = await playwright.chromium.connectOverCDP(this._relay.cdpEndpoint());
|
||||||
|
@ -22,6 +22,18 @@ import type { FullConfig } from '../config.js';
|
|||||||
|
|
||||||
export async function runWithExtension(config: FullConfig, abortController: AbortController) {
|
export async function runWithExtension(config: FullConfig, abortController: AbortController) {
|
||||||
const contextFactory = await startCDPRelayServer(config.browser.launchOptions.channel || 'chrome', abortController);
|
const contextFactory = await startCDPRelayServer(config.browser.launchOptions.channel || 'chrome', abortController);
|
||||||
const serverBackendFactory = () => new BrowserServerBackend(config, contextFactory);
|
|
||||||
|
let backend: BrowserServerBackend | undefined;
|
||||||
|
const serverBackendFactory = () => {
|
||||||
|
if (backend)
|
||||||
|
throw new Error('Another MCP client is still connected. Only one connection at a time is allowed.');
|
||||||
|
backend = new BrowserServerBackend(config, contextFactory);
|
||||||
|
backend.onclose = () => {
|
||||||
|
contextFactory.clientDisconnected();
|
||||||
|
backend = undefined;
|
||||||
|
};
|
||||||
|
return backend;
|
||||||
|
};
|
||||||
|
|
||||||
await mcpTransport.start(serverBackendFactory, config.server);
|
await mcpTransport.start(serverBackendFactory, config.server);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user