ComfyUI Extension: net tool node for comfyui

Authored by LyazS

Created

Updated

4 stars

A net tool node for comfyui, rewrite from comfyui-tooling-nodes but support more big data sending.

Custom Nodes (0)

    README

    Introduction

    rewrite from https://github.com/Acly/comfyui-tooling-nodes

    • but support more big data
    • can receive batch imgs
    • can send batch imgs much more than 4MB

    How I use it to send batch imgs

    def _is_continuous(self, img_data):
        keys = sorted(img_data.keys())
        return keys == list(range(len(keys)))
    def _merge_base64_to_pil(self, allb64):
        result = {}
        for node, node_data in allb64.items():
            result[node] = []
            for img_index, img_data in node_data.items():
                if not self._is_continuous(img_data):
                    print(
                        f"Skipping non-continuous image: node_{node}_image_{img_index}"
                    )
                    continue
    
                full_b64 = "".join(value for _, value in sorted(img_data.items()))
    
                try:
                    img_bytes = base64.b64decode(full_b64)
                    img = Image.open(io.BytesIO(img_bytes))
                    result[node].append(img)
                    logger.info(f"Processed image: node_{node}_image_{img_index}")
                except Exception as e:
                    logger.error(
                        f"Error processing image: node_{node}_image_{img_index}. Error: {str(e)}"
                    )
    
        return result
    
    async def _get_images(self, ws, prompt, client_id):
        prompt_id = (await self._queue_prompt(prompt, client_id))["prompt_id"]
    
        allb64 = {}
        try:
            async for msg in ws:
                if msg.type == aiohttp.WSMsgType.TEXT:
                    message = json.loads(msg.data)
                    if message["type"] == "progress" and message.get("data"):
                        pass
                    if message["type"] == "executing" and message.get("data"):
                        data = message["data"]
                        if data["node"] is None and data["prompt_id"] == prompt_id:
                            break
                    if message["type"] == "ntlb64part" and message.get("data"):
                        mdata = message["data"]
                        nodelabel = mdata["nodelabel"]
                        img_idx = mdata["img_idx"]
                        part_idx = mdata["part_idx"]
                        part_b64 = mdata["part_b64"]
                        if nodelabel not in allb64:
                            allb64[nodelabel] = {}
                            pass
                        if img_idx not in allb64[nodelabel]:
                            allb64[nodelabel][img_idx] = {}
                            pass
                        allb64[nodelabel][img_idx][part_idx] = part_b64
                        pass
        except aiohttp.ClientError as ex:
            raise Exception("WebSocket error: " + str(ex))
    
        output_images = self._merge_base64_to_pil(allb64)
        return output_images
    
    @asynccontextmanager
    async def websocket_connect(url):
        async with aiohttp.ClientSession() as session:
            async with session.ws_connect(url) as ws:
                try:
                    yield ws
                except aiohttp.ClientError as ex:
                    raise Exception("WebSocket connection error: " + str(ex))
    
    async with websocket_connect(url) as ws:
        node_outputs = await self._get_images(ws, drawconfig, self._client_id)
        images = fetchImgsFromNode(outputpath, node_outputs, ftype=2)