跳到正文

Port / Event / State API

跨窗口通信中枢(PortHub)提供三类能力:

  • port.*:命名通道与点对点消息
  • event.*:跨窗口事件广播/定向投递
  • state.*:共享键值状态(支持 TTL)

方法调用使用 dot 格式(如 port.connect),事件监听使用 colon 格式(如 port:messagestate:changed)。

Port API

port.connect

创建命名端口。

参数类型必填说明
namestring可选;默认 。

返回值(成功):

json
{
  "portId": "port_00000001",
  "name": "lyrics",
  "windowId": "main"
}

返回值(失败):

json
{ "error": "Port name is required", "code": "INVALID_PARAMS" }
javascript
const port = await fb2k.invoke('port.connect', { name: 'lyrics' });
console.log('端口 ID:', port.portId);

port.disconnect

销毁端口。

参数类型必填说明
portIdstring可选;默认 。

返回值(成功): { "success": true }

返回值(失败):

json
{ "error": "Port not found", "code": "PORT_NOT_FOUND" }
javascript
await fb2k.invoke('port.disconnect', { portId: 'port_00000001' });

port.postMessage

向同名通道的其它端口发送消息(不回送给自身)。

参数类型必填说明
messagejson必填。
portIdstring可选;默认 。

返回值(成功):

json
{ "success": true, "recipients": 2 }

返回值(失败):

json
{ "success": false, "error": "Port not found", "code": "PORT_NOT_FOUND" }
javascript
await fb2k.invoke('port.postMessage', {
    portId: 'port_00000001',
    message: { text: 'hello' }
});

port.postMessageTo

向指定端口发送消息。

参数类型必填说明
messagejson必填。
portIdstring可选;默认 。
targetPortIdstring可选;默认 。

返回值:

json
{ "success": true }

失败时可能返回:PORT_NOT_FOUND / TARGET_NOT_FOUND

javascript
await fb2k.invoke('port.postMessageTo', {
    portId: 'port_00000001',
    targetPortId: 'port_00000002',
    message: 'sync'
});

port.getPorts

获取端口列表(可选按 name 过滤)。权威源:src/api/PortApi.cpp:108-114PortHub::GetPorts

参数类型必填默认值说明
namestring可省略可选通道名过滤;省略则返回全部端口。

返回值:

json
{
  "success": true,
  "ports": [
    { "portId": "port_00000001", "name": "lyrics", "windowId": "main" }
  ]
}
javascript
const result = await fb2k.invoke('port.getPorts', { name: 'lyrics' });
console.log(`找到 ${result.ports.length} 个端口`);

Event API

event.emit

广播自定义事件到所有窗口。

参数类型必填说明
eventstring可选;默认 。
excludeSelfboolean可选;默认 false。
payloadobject可选;默认 {}。

返回值:

json
{ "success": true, "recipients": 3 }

接收端实际收到的事件 envelope 结构:

json
{ "payload": { ... }, "sourceWindowId": "main" }
javascript
await fb2k.invoke('event.emit', {
    event: 'ui:themeChanged',
    payload: { theme: 'dark' }
});

event.emitTo

定向投递事件到指定窗口。

参数类型必填说明
eventstring可选;默认 。
payloadobject可选;默认 {}。
targetWindowIdstring可选;默认 。

返回值:

json
{ "success": true }
javascript
await fb2k.invoke('event.emitTo', {
    event: 'lyrics:update',
    targetWindowId: 'popup_01',
    payload: { line: 5 }
});

State API

state.get

读取共享状态。

参数类型必填说明
keystring可选;默认 。

返回值: {"code":"...","error":"..."}

返回值(存在):

json
{ "key": "lyrics:offset", "value": 120, "exists": true, "expiresAt": 1760000000000 }

返回值(不存在):

json
{ "value": null, "exists": false }
javascript
const result = await fb2k.invoke('state.get', { key: 'lyrics:offset' });
if (result.exists) console.log('偶移:', result.value);

state.set

设置共享状态。

参数类型必填说明
keystring可选;默认 。
silentboolean可选;默认 false。
ttlMsinteger可选;默认 omitted。
valuejson必填。

返回值:

json
{ "success": true, "expiresAt": 1760000000000 }
javascript
await fb2k.invoke('state.set', {
    key: 'lyrics:offset',
    value: 120,
    ttlMs: 60000
});

state.delete

删除共享状态。

参数类型必填说明
keystring可选;默认 。

返回值:

json
{ "success": true, "existed": true }
javascript
await fb2k.invoke('state.delete', { key: 'lyrics:offset' });

state.keys

列出状态键,支持 * 通配。权威源:src/api/PortApi.cpp:188-191PortHub::GetStateKeys

参数类型必填默认值说明
patternstring*过滤模式;* 匹配全部,末尾 * 为前缀匹配。

返回值:

json
{ "success": true, "keys": ["lyrics:offset", "lyrics:theme"] }
javascript
const result = await fb2k.invoke('state.keys', { pattern: 'lyrics:*' });
console.log('状态键:', result.keys);

事件列表(PortHub)

事件名触发时机主要字段
port:connected创建端口portId, name, windowId
port:disconnected销毁端口/窗口清理portId, name, windowId
port:message收到端口消息portId, sourcePortId, sourceWindowId, message
state:changedstate.set 且非 silentkey, value, previousValue, sourceWindowId, expiresAt?
state:deletedstate.delete 或 TTL 到期key, sourceWindowId, reason

合同补充

以下章节补齐严格参数审计发现的公开 contract;不会改变前文的已有说明。

Contract 补充:state.set

经复核的补充 contract。权威源:src/api/PortApi.cpp:158-175

参数类型必填默认值说明
keystring``可选;默认 。
silentbooleanfalse可选;默认 false。
ttlMsinteger可省略可选;默认 omitted。
valuejson必填。

返回字段

字段类型可选
codestring
errorstring
successboolean

语义:省略可选参数时使用 handler 默认值;失败分支及错误字段以该源文件为准。

js
const result = await fb2k.invoke('state.set', { key: /* value */, silent: /* value */, ttlMs: /* value */, value: /* value */ });

路由、状态与事件 envelope

  • port.connect 将新端口绑定到调用窗口。只有该 owner 能断开端口或通过该端口发送;port.postMessage 会排除发送端口,并将 port:message 路由到同名的其他端口。
  • event.emit 广播指定事件名,event.emitTo 定向到一个窗口。接收方获得 envelope { payload, sourceWindowId };只有 event.emit 使用 excludeSelf。应用自定义事件名使用 namespace:eventName 约定,例如 ui:themeChangedlyrics:update
  • state.* 是进程级 PortHub 单例持有的内存状态。在当前 foobar2000 进程中,本组件的多个 WebView 窗口可共享它;但它不会写入磁盘、进程重启后丢失,也不是跨进程或 SMP/全局持久化机制。它与 SDK 的 fb.state 播放状态镜像不同。
  • 键不存在时,state.get 返回 exists: falsevalue: nullstate.set 同时要求 keyvalue;正数 ttlMs 会创建过期时间戳,silent: true 会抑制 state:changed
  • state.delete 返回 existed。显式删除会发出 reason: "deleted"state:deleted;过期会发出相同事件,但 reason"expired",且 sourceWindowId 为空。
  • 公开 PortHub 事件包括 port:connectedport:disconnectedport:messagestate:changedstate:deleted。它们的 payload 由 src/api/PortHub.cpp 发出。