纯接口 · 多功能分发
一个 openSocketID 通过 optional 参数切换不同操作。适合命令式接口——用同一个入口,靠参数决定执行什么。
真实节点:Everything 搜索节点
模式
调用方 ──▶ [search?function=search&query=*.txt&max_results=20] ──▶ Everything
调用方 ◀── [files=readme.md|src/main.py;count=2;status=成功] ──── Everything
三个操作共用 openSocketID: "search",靠 function 参数区别。
清单
plugin_manifest.json:
{
"app_id": "com.everything.node",
"plugin_name": "Everything 搜索节点",
"author": "HXH",
"version": "v1.0.0",
"description": "使用 Everything 搜索引擎执行文件搜索",
"download_url": "https://github.com/hxh230802/Everything_node/releases/latest",
"auto_start": "false",
"exe_path": "Everything_node.exe"
}
FuncList.json — 一个功能条目包含多个操作,参数用 optional 切换:
"openSocket": {
"search": {
"appID": "com.everything.node",
"openSocketID": "search",
"description": "文件搜索、计数、打开文件夹",
"args": {
"function": {
"type": "optional",
"description": "操作类型",
"options": [
["搜索文件", "search"],
["仅获取数量", "search_count"],
["打开所在文件夹", "open_folder"]
]
},
"query": { "type": "input", "description": "搜索关键词" },
"max_results": { "type": "input", "description": "最大返回数", "defaultVal": "20" }
},
"returns": [
["状态", "status"],
["文件列表", "files"],
["结果数量", "count"]
]
}
}
通信代码
from knotlink import OpenSocketResponser, KLKVMap
APPID = "com.everything.node"
SOCKET_ID = "search"
responser = OpenSocketResponser(APPID, SOCKET_ID)
def handle_request(data: str) -> str:
req = KLKVMap()
req.deserialize(data)
func = req.get("function", "search")
if func == "search":
query = req.get("query", "")
max_n = int(req.get("max_results", "20"))
return do_search(query, max_n) # 返回 files|count
if func == "search_count":
return str(count_all(req.get("query", "")))
if func == "open_folder":
open_first_result(req.get("query", ""))
return "success=true"
responser.set_RecvFunc(handle_request)
input("按回车退出。\n")
关键点
- 一个 socketID 承载多种操作 —
FuncList.json里只建一个功能条目,optional 的options枚举所有操作 - 功能 ≠ 接口 — 三个操作用同一个
openSocketID: "search",业务层通过function参数分发 - optional 参数 — 调用方在 API 测试页看到下拉菜单,只能选预设选项,不会传错值