Add ping/pong keep-alive to prevent service worker termination
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Playwriter MCP",
|
"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.",
|
"description": "Automate your Browser using Cursor, Claude, VS Code. More capable and context efficient than Playwright MCP.",
|
||||||
"permissions": ["debugger", "tabGroups", "contextMenus", "tabs"],
|
"permissions": ["debugger", "tabGroups", "contextMenus", "tabs"],
|
||||||
"host_permissions": ["<all_urls>"],
|
"host_permissions": ["<all_urls>"],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mcp-extension",
|
"name": "mcp-extension",
|
||||||
"version": "0.0.61",
|
"version": "0.0.64",
|
||||||
"description": "Playwright MCP Browser Extension",
|
"description": "Playwright MCP Browser Extension",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -41,6 +41,23 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|||||||
reject: (error: Error) => void
|
reject: (error: Error) => void
|
||||||
}>()
|
}>()
|
||||||
let extensionMessageId = 0
|
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({
|
function logCdpMessage({
|
||||||
direction,
|
direction,
|
||||||
@@ -504,6 +521,7 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|||||||
}
|
}
|
||||||
|
|
||||||
extensionWs = ws
|
extensionWs = ws
|
||||||
|
startExtensionPing()
|
||||||
logger?.log('Extension connected with clean state')
|
logger?.log('Extension connected with clean state')
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -517,7 +535,7 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('id' in message) {
|
if (message.id !== undefined) {
|
||||||
const pending = extensionPendingRequests.get(message.id)
|
const pending = extensionPendingRequests.get(message.id)
|
||||||
if (!pending) {
|
if (!pending) {
|
||||||
logger?.log('Unexpected response with id:', message.id)
|
logger?.log('Unexpected response with id:', message.id)
|
||||||
@@ -531,6 +549,8 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|||||||
} else {
|
} else {
|
||||||
pending.resolve(message.result)
|
pending.resolve(message.result)
|
||||||
}
|
}
|
||||||
|
} else if (message.method === 'pong') {
|
||||||
|
// Keep-alive response, nothing to do
|
||||||
} else if (message.method === 'log') {
|
} else if (message.method === 'log') {
|
||||||
const { level, args } = message.params
|
const { level, args } = message.params
|
||||||
const logFn = (logger as any)?.[level] || logger?.log
|
const logFn = (logger as any)?.[level] || logger?.log
|
||||||
@@ -681,7 +701,8 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|||||||
},
|
},
|
||||||
|
|
||||||
onClose(event, ws) {
|
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,
|
// If this is an old connection closing after we've already established a new one,
|
||||||
// don't clear the global state
|
// don't clear the global state
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export type ExtensionCommandMessage = ForwardCDPCommand
|
|||||||
|
|
||||||
export type ExtensionResponseMessage = {
|
export type ExtensionResponseMessage = {
|
||||||
id: number
|
id: number
|
||||||
|
method?: undefined
|
||||||
result?: any
|
result?: any
|
||||||
error?: string
|
error?: string
|
||||||
}
|
}
|
||||||
@@ -30,6 +31,7 @@ export type ExtensionResponseMessage = {
|
|||||||
export type ExtensionEventMessage =
|
export type ExtensionEventMessage =
|
||||||
{
|
{
|
||||||
[K in keyof ProtocolMapping.Events]: {
|
[K in keyof ProtocolMapping.Events]: {
|
||||||
|
id?: undefined
|
||||||
method: 'forwardCDPEvent'
|
method: 'forwardCDPEvent'
|
||||||
params: {
|
params: {
|
||||||
method: CDPEventFor<K>['method']
|
method: CDPEventFor<K>['method']
|
||||||
@@ -40,6 +42,7 @@ export type ExtensionEventMessage =
|
|||||||
}[keyof ProtocolMapping.Events]
|
}[keyof ProtocolMapping.Events]
|
||||||
|
|
||||||
export type ExtensionLogMessage = {
|
export type ExtensionLogMessage = {
|
||||||
|
id?: undefined
|
||||||
method: 'log'
|
method: 'log'
|
||||||
params: {
|
params: {
|
||||||
level: 'log' | 'debug' | 'info' | 'warn' | 'error'
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user