Add ping/pong keep-alive to prevent service worker termination

This commit is contained in:
Tommy D. Rossi
2025-12-31 16:15:17 +01:00
parent 02fda90578
commit be1b9514d3
4 changed files with 39 additions and 5 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Playwriter MCP",
"version": "0.0.61",
"version": "0.0.64",
"description": "Automate your Browser using Cursor, Claude, VS Code. More capable and context efficient than Playwright MCP.",
"permissions": ["debugger", "tabGroups", "contextMenus", "tabs"],
"host_permissions": ["<all_urls>"],
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "mcp-extension",
"version": "0.0.61",
"version": "0.0.64",
"description": "Playwright MCP Browser Extension",
"private": true,
"repository": {
+23 -2
View File
@@ -41,6 +41,23 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
reject: (error: Error) => void
}>()
let extensionMessageId = 0
let extensionPingInterval: ReturnType<typeof setInterval> | null = null
function startExtensionPing() {
if (extensionPingInterval) {
clearInterval(extensionPingInterval)
}
extensionPingInterval = setInterval(() => {
extensionWs?.send(JSON.stringify({ method: 'ping' }))
}, 5000)
}
function stopExtensionPing() {
if (extensionPingInterval) {
clearInterval(extensionPingInterval)
extensionPingInterval = null
}
}
function logCdpMessage({
direction,
@@ -504,6 +521,7 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
}
extensionWs = ws
startExtensionPing()
logger?.log('Extension connected with clean state')
},
@@ -517,7 +535,7 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
return
}
if ('id' in message) {
if (message.id !== undefined) {
const pending = extensionPendingRequests.get(message.id)
if (!pending) {
logger?.log('Unexpected response with id:', message.id)
@@ -531,6 +549,8 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
} else {
pending.resolve(message.result)
}
} else if (message.method === 'pong') {
// Keep-alive response, nothing to do
} else if (message.method === 'log') {
const { level, args } = message.params
const logFn = (logger as any)?.[level] || logger?.log
@@ -681,7 +701,8 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
},
onClose(event, ws) {
logger?.log('Extension disconnected')
logger?.log(`Extension disconnected: code=${event.code} reason=${event.reason || 'none'}`)
stopExtensionPing()
// If this is an old connection closing after we've already established a new one,
// don't clear the global state
+14 -1
View File
@@ -19,6 +19,7 @@ export type ExtensionCommandMessage = ForwardCDPCommand
export type ExtensionResponseMessage = {
id: number
method?: undefined
result?: any
error?: string
}
@@ -30,6 +31,7 @@ export type ExtensionResponseMessage = {
export type ExtensionEventMessage =
{
[K in keyof ProtocolMapping.Events]: {
id?: undefined
method: 'forwardCDPEvent'
params: {
method: CDPEventFor<K>['method']
@@ -40,6 +42,7 @@ export type ExtensionEventMessage =
}[keyof ProtocolMapping.Events]
export type ExtensionLogMessage = {
id?: undefined
method: 'log'
params: {
level: 'log' | 'debug' | 'info' | 'warn' | 'error'
@@ -47,4 +50,14 @@ export type ExtensionLogMessage = {
}
}
export type ExtensionMessage = ExtensionResponseMessage | ExtensionEventMessage | ExtensionLogMessage
export type ExtensionPongMessage = {
id?: undefined
method: 'pong'
}
export type ServerPingMessage = {
method: 'ping'
id?: undefined
}
export type ExtensionMessage = ExtensionResponseMessage | ExtensionEventMessage | ExtensionLogMessage | ExtensionPongMessage