Skip to main content

快速开始 — 跟着搭一个节点

不克隆一个现成项目照着跑——那样手没动、决策也不是你的。这篇带你以 消息提醒 为例,跟着逻辑把一个真实节点搭出来:读懂 5 块通信代码 → 填功能清单 → 填身份清单 → 提 PR。搭完,你的程序就接入了 KnotLink。

想直接动手 + 署名收录?

本文用的模板就是 KNodeIndex 新手训练营。拷一个语言项目、跟着填、自检绿了提 PR,你的名字就挂在节点索引里 → 新手训练营 practice/


流程

拿模板 → 读懂 5 块代码 → 填 FuncList → 填 manifest → 提 PR

第 0 步:拿到模板

模板在训练营里,每种语言是一个自带 SDK、能直接编译运行的完整项目

git clone https://github.com/KnotLink-Protocol/KNodeIndex
cd KNodeIndex/practice/_exercise/python # 或 javascript / java / csharp / cpp

一个语言项目长这样(以 Python 为例):

python/
├── main.py # 通信代码(本文第 2 步)
├── plugin_manifest.json # 身份清单(第 4 步)
├── FuncList.json # 功能清单(第 3 步)
├── README.md # 项目说明
├── logo.png # 节点图标
├── requirements.txt # 依赖
└── knotlink/ # 打包好的 SDK,无需安装

第 1 步:想清楚要提供什么,定 AppID

动手前先想:这个节点对外提供什么?消息提醒很简单——

接口 show:别人调用它、传一条消息,它打印出来并回 OK信号 messageShown:打印完广播一条「已显示」,带上消息内容和时间。

AppID倒置域名、把你的名字嵌进去:

com.github.你的用户名.msgreminder

这样它在整个 KnotLink 网络里天然唯一,也是你的署名。一旦发布就别改了。

旧格式兼容

早期项目用 0x 开头的 8 位十六进制(如 0x00000014),KnotLink 继续支持。新项目推荐倒置域名,可读性更好。详见 核心概念 — 标识符命名规范


第 2 步:读懂通信代码(5 块,KLUDF 标准化)

main.* 里的代码已经按节点的执行逻辑分成 5 块、完整写好并带注释。你只要读懂每块,然后把 ① 里的 APPID 换成你自己。

干什么
① 上线声明身份(AppID + 接口 + 信号),当「回复者」连上 KnotLink
② 解析被调用时,用 KLUDFKLKVMap)把 key=value 请求解析出参数
③ 处理你的业务:把消息打印出来
④ 报告KLUDF 打包 content + time,广播 messageShown 信号
⑤ 回复告诉调用方成功(OK
from knotlink import OpenSocketResponser, SignalSender, KLKVMap
import time

# ① 上线:声明身份,作为「回复者」连上 KnotLink
APPID = "com.github.你的用户名.msgreminder" # ← 换成你自己
OPENSOCKET_ID = "show"
SIGNAL_ID = "messageShown"
responser = OpenSocketResponser(APPID, OPENSOCKET_ID)
sender = SignalSender(APPID, SIGNAL_ID)


def handle_request(data: str) -> str:
# ② 用 KLUDF 解析请求,按名取参数
req = KLKVMap()
req.deserialize(data)
message = req.get("msgContext", "默认消息")
# ③ 处理:打印消息
print(f"收到:{message}")
# ④ 用 KLUDF 打包 content + time,广播信号
out = KLKVMap()
out["content"] = message
out["time"] = time.strftime("%Y-%m-%d %H:%M:%S")
sender.emitt(out.serialize())
# ⑤ 回复
return "OK"


responser.set_RecvFunc(handle_request) # 回调返回值自动回传
input("按回车退出。\n")
数据进出都走 KLUDF

请求和信号数据都是 key1=value1;key2=value2 格式,用 KLKVMap 标准化处理:deserialize 解析、get 取参数、serialize 打包。各语言 API 一致(Python/C++/C# 回调返回值自动回传,Java/JS 要显式 sendBack)。

JS / Java 的官方 SDK 暂未内置 KLKVMap,训练营已在打包 SDK 里补上(knotlink/KLKVMap.jsknotlink-sdk/KLKVMap.java)。八种语言的完整示例见 编写代码


第 3 步:填 FuncList.json

告诉工具链你的节点有哪些接口和信号——appID 与代码、manifest 三处保持一致:

{
"appName": "消息提醒",
"specVersion": "1.0",
"manifestVersion": "1.0.0",
"openSocket": {
"ShowMsg": {
"appID": "com.github.你的用户名.msgreminder",
"openSocketID": "show",
"description": "打印收到的消息并回复 OK",
"args": {
"msgContext": {
"type": "input",
"description": "消息内容",
"defaultVal": "测试消息"
}
},
"returns": []
}
},
"signal": {
"messageShown": {
"appID": "com.github.你的用户名.msgreminder",
"signalID": "messageShown",
"description": "消息显示后广播",
"returns": {
"content": { "description": "已显示的消息内容" },
"time": { "description": "消息显示的时间" }
}
}
}
}
  • openSocketID / signalID 要和代码里一致(show / messageShown)。
  • args 三种参数类型:input(运行时输入)、optional(下拉选项)、static(固定值)。
  • 注意 signal.returns对象格式 { "字段": { "description": "..." } },不是数组。

不想手写?用 FLEditor 可视化编辑。详见 填写功能清单


第 4 步:填 plugin_manifest.json

告诉平台你是谁、怎么启动:

{
"app_id": "com.github.你的用户名.msgreminder",
"plugin_name": "消息提醒",
"author": "你的用户名",
"version": "v1.0.0",
"description": "打印收到的消息",
"download_url": "https://github.com/你的用户名/msgreminder/releases/latest",
"auto_start": "true",
"exe_path": "MsgNotification.exe"
}
字段填什么
app_id和第 1 步、代码、FuncList 一致
plugin_name显示名称,和 FuncList 的 appName 一致
author你的名字
download_url下载地址(GitHub Releases 等)
exe_path可执行文件名(源码项目可填源码入口文件)

节点类型由目录决定:插入式放 plugin/(用 plugin_manifest.json),独立式放 standalone/(用 standalone_manifest.json)。详见 打包与分发


第 5 步:提 PR,署名收录

练手(训练营) → 提交到 practice/

  1. Fork KNodeIndex
  2. 把你填好的语言项目复制成 practice/<你的GitHub用户名>/
  3. 本地自检:node validate-practice.js(全绿再提)
  4. 提 PR,合并后你的练习就留档在 practice/ 里 🎉

真实节点 → 提交到 plugin/standalone/

  1. 复制 plugin/_template/ → 重命名为 节点名-作者名
  2. 放入:FuncList.json + plugin_manifest.json + logo.png + README.md
  3. 本地自检:node validate-nodes.js
  4. 提 PR,合并后你的名字挂在节点索引里

还想看现成的?

官方案例集有四种标准模式的完整清单和代码:官方案例集