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.pySaveImage 的代码)


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

汇智网翻译整理,转载请标明出处