ComfyUI消息机制
本文介绍Comfy服务端(Python)和客户端(JavaScript)之间的消息传递。
在执行期间(或队列状态发生变化时), PromptExecutor
通过 PromptServer 的 send_sync
方法将消息发送回客户端。
这些消息由 api.js
中定义的套接字事件侦听器接收(在撰写本文时大约在第 90 行,或搜索 this.socket.addEventListener
),它为任何已知消息类型创建一个 CustomEvent
对象,并将其分派给任何已注册的侦听器。
客户端的JS扩展(Extension)可以按照标准 Javascript 习惯用法注册接收事件,通常在 setup()
函数中完成:
api.addEventListener(message_type, messageHandler);
如果 message_type
不是内置类型之一,它将自动添加到已知消息类型列表中。消息 messageHandler
将使用 CustomEvent
对象调用,该对象扩展套接字引发的事件以添加 .detail 属性,该属性是服务器发送的数据的字典。因此用法一般如下:
function messageHandler(event) {
if (event.detail.node == aNodeIdThatIsInteresting) {
// do something with event.detail.other_things
}
}
1、内置消息类型
在执行期间(或队列状态发生变化时), PromptExecutor
通过 PromptServer 的 send_sync
方法将以下消息发送回客户端。客户端的JS扩展可以注册为其中任何消息的监听器。
事件 | 触发时机 | 数据 |
---|---|---|
execution_start | 提示即将运行时 | prompt_id |
execution_error | 执行过程中发生错误时 | prompt_id,以及附加信息 |
execution_interrupted | 执行因节点引发 InterruptProcessingException 而停止时 | prompt_id、node_id、node_type 和 executed(已执行节点列表) |
execution_cached | 执行开始时 | prompt_id、nodes(由于可以使用缓存的输出而被跳过的节点列表) |
executing | 即将执行新节点时 | node(node id 或 None 表示完成)、prompt_id |
executed | 节点返回 ui 元素时 | node(node id)、prompt_id、output |
progress | 执行实现所需钩子的节点期间 | node(node id)、prompt_id、value、max |
status | 队列状态改变时 | exec_info,保存队列中条目数的字典queue_remaining |
2、使用 executed
尽管名称如此,但每当执行一个操作时,并不会发送 executed
消息节点完成执行(与执行不同),但仅当节点返回 ui 更新时才会完成。
为此,Python服务端节点的主函数需要返回一个字典而不是元组:
# at the end of my main method
return { "ui":a_new_dictionary, "result": the_tuple_of_output_values }
a_new_dictionary
随后将作为执行消息中的输出值发送。如果节点没有输出,则可以省略结果键(例如,参见 nodes.py
中 SaveImage
的代码)
3、自定义消息类型
如上所述,在客户端,只需注册为唯一消息类型名称的侦听器即可添加自定义消息类型:
api.addEventListener("my.custom.message", messageHandler);
在服务器上,代码同样简单:
from server import PromptServer
# then, in your main execution function (normally)
PromptServer.instance.send_sync("my.custom.message", a_dictionary)
4、获取 node_id
大多数内置消息在节点的值中包含当前节点 id。你可能也想这样做。
node_id
在服务器端通过隐藏输入可用,该输入通过 INPUT_TYPES
字典中的隐藏键获得:
@classmethod
def INPUT_TYPES(s):
return {"required" : { }, # whatever your required inputs are
"hidden": { "node_id": "UNIQUE_ID" } } # Add the hidden key
def my_main_function(self, required_inputs, node_id):
# do some things
PromptServer.instance.send_sync("my.custom.message", {"node": node_id, "other_things": etc})
原文链接:ComfyUI Client-Server Messages
汇智网翻译整理,转载请标明出处