Tcp request node issue

I am using node-red to do a low code flow development. When I use the below flow to implement the request, something unexpected happens.

http in > tcp request > http response

the tcp request will call another remote server to retrieve the data. The single test is fine with this flow. But when I use the Jmeter to do the performance tests, I found the request data can't map to the response data, and some of the requests will hang utill the timeout. It looks like this:
request 1 arrives > my flow send the data A to remote tcp server > request 2 arrives >my flow send the data B to remote tcp server > remote tcp server returns data A and close the tcp stream > return data A to request 2 > request 1 hang until timeout.

I am using the time type tcp request with 0ms setting. I am not good at nodejs, I can't figure out the deep reason for this behavior.

Anyone can help me with this?

something wrong with the tcp request node when handling lots of concurrent requests at one time. I used a function node to create a new net.Socket for each request to avoid the issue for now.

Can you provide a demo flow. Select the nodes to export them press ctrl+e. Paste the flow JSON in your reply.

[
    {
        "id": "cb3b6c2a41cf72f0",
        "type": "tcp in",
        "z": "1282c65dbdf9f53c",
        "name": "监听11111",
        "server": "server",
        "host": "",
        "port": "11111",
        "datamode": "stream",
        "datatype": "buffer",
        "newline": "",
        "topic": "",
        "trim": false,
        "base64": false,
        "tls": "",
        "x": 240,
        "y": 180,
        "wires": [
            [
                "697533c7825e1ced",
                "03818d515d781ad3"
            ]
        ]
    },
    {
        "id": "388fba5269805c57",
        "type": "tcp out",
        "z": "1282c65dbdf9f53c",
        "name": "",
        "host": "",
        "port": "",
        "beserver": "reply",
        "base64": false,
        "end": false,
        "tls": "",
        "x": 570,
        "y": 180,
        "wires": []
    },
    {
        "id": "887d3185952d99a9",
        "type": "change",
        "z": "1282c65dbdf9f53c",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "flag",
                "pt": "msg",
                "to": "",
                "tot": "date"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 260,
        "y": 400,
        "wires": [
            [
                "8c5fa82733fd8f02"
            ]
        ]
    },
    {
        "id": "2e2d787232b8ef60",
        "type": "http in",
        "z": "1282c65dbdf9f53c",
        "name": "",
        "url": "/test",
        "method": "post",
        "upload": false,
        "swaggerDoc": "",
        "x": 100,
        "y": 460,
        "wires": [
            [
                "887d3185952d99a9"
            ]
        ]
    },
    {
        "id": "2dfcbf03c16f805b",
        "type": "http response",
        "z": "1282c65dbdf9f53c",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 710,
        "y": 420,
        "wires": []
    },
    {
        "id": "2828b02abccf1a4f",
        "type": "tcp request",
        "z": "1282c65dbdf9f53c",
        "name": "",
        "server": "localhost",
        "port": "11111",
        "out": "time",
        "ret": "buffer",
        "splitc": "0",
        "newline": "",
        "trim": false,
        "tls": "",
        "x": 470,
        "y": 480,
        "wires": [
            [
                "672f219c956939e4"
            ]
        ]
    },
    {
        "id": "8c5fa82733fd8f02",
        "type": "function",
        "z": "1282c65dbdf9f53c",
        "name": "print request",
        "func": "node.log(\"flag:\" + msg.flag + \",payload:\" + msg.payload);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [
            {
                "var": "net",
                "module": "net"
            }
        ],
        "x": 290,
        "y": 480,
        "wires": [
            [
                "2828b02abccf1a4f"
            ]
        ]
    },
    {
        "id": "672f219c956939e4",
        "type": "function",
        "z": "1282c65dbdf9f53c",
        "name": "print response",
        "func": "node.log(\"flag:\" + msg.flag + \",payload:\" + msg.payload);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 660,
        "y": 480,
        "wires": [
            [
                "2dfcbf03c16f805b"
            ]
        ]
    },
    {
        "id": "697533c7825e1ced",
        "type": "function",
        "z": "1282c65dbdf9f53c",
        "name": "模拟返回",
        "func": "// 函数实现,参数 delay 单位 毫秒 ;\nfunction sleep(delay) {\n    var start = (new Date()).getTime();\n    while ((new Date()).getTime() - start < delay) {\n        // 使用  continue 实现;\n        continue;\n    }\n}\n\n// 调用方法,同步执行,阻塞后续程序的执行;\nsleep(Math.random());\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 420,
        "y": 180,
        "wires": [
            [
                "388fba5269805c57"
            ]
        ]
    },
    {
        "id": "03818d515d781ad3",
        "type": "debug",
        "z": "1282c65dbdf9f53c",
        "name": "debug 5",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 540,
        "y": 80,
        "wires": []
    },
    {
        "id": "94d7958c51762c37",
        "type": "inject",
        "z": "1282c65dbdf9f53c",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 90,
        "y": 380,
        "wires": [
            [
                "887d3185952d99a9"
            ]
        ]
    }
]

the flow is a simple request & resonse demo.

Once you use jmeter to test the /test with a random payload, you will find logs like below:

 573 25 Jul 12:53:28 - [info] [function:function 4] flag:1658724808303,payload:325726721
 574 25 Jul 12:53:28 - [info] [function:function 4] flag:1658724808304,payload:694579152
 575 25 Jul 12:53:28 - [info] [function:function 5] flag:1658724808304,payload:325726721694579152

which indicates the tcp request node content was incorrect.

ok, 2 things.

  1. JavaScript / NodeJS is an event driven async runtime - do not try to introduce a delay with a while loop - you will block the event loop. Instead, use the built in delay node
  2. It seems the TCP node does not graciously handle concurrent requests. Off the top of my head, you could limit the TCP Request node to one transaction using something like the semaphore node would be ideal (or a DIY fifo that you can push/peak/shift)

Here is a demo using built in nodes. NOTE: The data must have a \n newline for the TCP node to know when to emit otherwise fast operations will cause multiple repsonses to be concatenated ...

[
    {
        "id": "2e2d787232b8ef60",
        "type": "http in",
        "z": "53d61a606f3a5b66",
        "name": "",
        "url": "/test",
        "method": "post",
        "upload": false,
        "swaggerDoc": "",
        "x": 740,
        "y": 620,
        "wires": [
            [
                "8c5fa82733fd8f02"
            ]
        ]
    },
    {
        "id": "2828b02abccf1a4f",
        "type": "tcp request",
        "z": "53d61a606f3a5b66",
        "name": "",
        "server": "localhost",
        "port": "11111",
        "out": "sit",
        "ret": "string",
        "splitc": " ",
        "newline": "\\n",
        "trim": false,
        "tls": "",
        "x": 1270,
        "y": 620,
        "wires": [
            [
                "672f219c956939e4",
                "7ee1f6c07bdd0146"
            ]
        ]
    },
    {
        "id": "8c5fa82733fd8f02",
        "type": "function",
        "z": "53d61a606f3a5b66",
        "name": "add flag",
        "func": "msg.flag = RED.util.generateId()\nnode.log(\"flag:\" + msg.flag + \",payload:\" + msg.payload);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [
            {
                "var": "crypto",
                "module": "crypto"
            }
        ],
        "x": 900,
        "y": 620,
        "wires": [
            [
                "2eeb96fd0e4f4d91",
                "93bf7d2106a6e741"
            ]
        ]
    },
    {
        "id": "672f219c956939e4",
        "type": "function",
        "z": "53d61a606f3a5b66",
        "name": "print response",
        "func": "node.log(\"flag:\" + msg.flag + \",payload:\" + msg.payload);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1480,
        "y": 620,
        "wires": [
            [
                "f34b20e3b48bf779"
            ]
        ]
    },
    {
        "id": "e57a3876b7e6f0fc",
        "type": "inject",
        "z": "53d61a606f3a5b66",
        "name": "test 3",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "3",
        "payloadType": "num",
        "x": 810,
        "y": 820,
        "wires": [
            [
                "9c397614b000e13e"
            ]
        ]
    },
    {
        "id": "9c397614b000e13e",
        "type": "function",
        "z": "53d61a606f3a5b66",
        "name": "make multiple messages",
        "func": "for (let index = 0; index < msg.payload; index++) {\n    const m = {\n        payload: \"*\" + Date.now() + \"*\\n\",\n        requestTimeout: 5000\n    }\n    node.send(m);\n}\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1010,
        "y": 800,
        "wires": [
            [
                "9647b5cb32858609"
            ]
        ]
    },
    {
        "id": "9647b5cb32858609",
        "type": "http request",
        "z": "53d61a606f3a5b66",
        "name": "",
        "method": "POST",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "http://192.168.1.61:1880/test",
        "tls": "",
        "persist": false,
        "proxy": "",
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 1230,
        "y": 800,
        "wires": [
            [
                "559855fe09055156"
            ]
        ]
    },
    {
        "id": "559855fe09055156",
        "type": "debug",
        "z": "53d61a606f3a5b66",
        "name": "done (4)",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1420,
        "y": 800,
        "wires": []
    },
    {
        "id": "daf26c52e601f08f",
        "type": "inject",
        "z": "53d61a606f3a5b66",
        "name": "test 1",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "1",
        "payloadType": "num",
        "x": 810,
        "y": 780,
        "wires": [
            [
                "9c397614b000e13e"
            ]
        ]
    },
    {
        "id": "1583264947bb0274",
        "type": "inject",
        "z": "53d61a606f3a5b66",
        "name": "test 50",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "50",
        "payloadType": "num",
        "x": 810,
        "y": 860,
        "wires": [
            [
                "9c397614b000e13e"
            ]
        ]
    },
    {
        "id": "d5f96f761e5259be",
        "type": "catch",
        "z": "53d61a606f3a5b66",
        "name": "",
        "scope": [
            "9647b5cb32858609"
        ],
        "uncaught": false,
        "x": 1050,
        "y": 900,
        "wires": [
            [
                "d8efe97e5f3574ee",
                "ebcce6b128a29a4f"
            ]
        ]
    },
    {
        "id": "d8efe97e5f3574ee",
        "type": "debug",
        "z": "53d61a606f3a5b66",
        "name": "err",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1210,
        "y": 960,
        "wires": []
    },
    {
        "id": "c42ffa50e3bfe661",
        "type": "inject",
        "z": "53d61a606f3a5b66",
        "name": "clear",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 810,
        "y": 1040,
        "wires": [
            [
                "e0cc99a96593c366"
            ]
        ]
    },
    {
        "id": "2eeb96fd0e4f4d91",
        "type": "link call",
        "z": "53d61a606f3a5b66",
        "name": "",
        "links": [
            "2f6841c7c64868c8"
        ],
        "linkType": "static",
        "timeout": "30",
        "x": 1080,
        "y": 620,
        "wires": [
            [
                "2828b02abccf1a4f"
            ]
        ]
    },
    {
        "id": "f34b20e3b48bf779",
        "type": "link call",
        "z": "53d61a606f3a5b66",
        "name": "",
        "links": [
            "84d8551b17812c30"
        ],
        "linkType": "static",
        "timeout": "30",
        "x": 1710,
        "y": 620,
        "wires": [
            [
                "2dfcbf03c16f805b"
            ]
        ]
    },
    {
        "id": "7ee1f6c07bdd0146",
        "type": "debug",
        "z": "53d61a606f3a5b66",
        "name": "3",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1470,
        "y": 560,
        "wires": []
    },
    {
        "id": "93bf7d2106a6e741",
        "type": "debug",
        "z": "53d61a606f3a5b66",
        "name": "1",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1050,
        "y": 560,
        "wires": []
    },
    {
        "id": "e0cc99a96593c366",
        "type": "link call",
        "z": "53d61a606f3a5b66",
        "name": "",
        "links": [
            "eea944fcfdf24a06"
        ],
        "linkType": "static",
        "timeout": "30",
        "x": 990,
        "y": 1040,
        "wires": [
            []
        ]
    },
    {
        "id": "ebcce6b128a29a4f",
        "type": "link call",
        "z": "53d61a606f3a5b66",
        "name": "",
        "links": [
            "84d8551b17812c30"
        ],
        "linkType": "static",
        "timeout": "30",
        "x": 1250,
        "y": 900,
        "wires": [
            []
        ]
    },
    {
        "id": "2937e3e3e75775f3",
        "type": "catch",
        "z": "53d61a606f3a5b66",
        "name": "",
        "scope": [
            "2e2d787232b8ef60",
            "8c5fa82733fd8f02",
            "2828b02abccf1a4f",
            "672f219c956939e4"
        ],
        "uncaught": false,
        "x": 1510,
        "y": 680,
        "wires": [
            [
                "c486a51ba28cdf47",
                "92ac7ce68a747a4b"
            ]
        ]
    },
    {
        "id": "92ac7ce68a747a4b",
        "type": "change",
        "z": "53d61a606f3a5b66",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "statusCode",
                "pt": "msg",
                "to": "500",
                "tot": "num"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1720,
        "y": 680,
        "wires": [
            [
                "2dfcbf03c16f805b"
            ]
        ]
    },
    {
        "id": "c486a51ba28cdf47",
        "type": "debug",
        "z": "53d61a606f3a5b66",
        "name": "err",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1670,
        "y": 740,
        "wires": []
    },
    {
        "id": "2dfcbf03c16f805b",
        "type": "http response",
        "z": "53d61a606f3a5b66",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 1950,
        "y": 640,
        "wires": []
    },
    {
        "id": "a4f8f71434887c90",
        "type": "group",
        "z": "53d61a606f3a5b66",
        "style": {
            "stroke": "#999999",
            "stroke-opacity": "1",
            "fill": "none",
            "fill-opacity": "1",
            "label": true,
            "label-position": "nw",
            "color": "#a4a4a4"
        },
        "nodes": [
            "cb3b6c2a41cf72f0",
            "388fba5269805c57",
            "03818d515d781ad3",
            "42d9edb4e0b8039a"
        ],
        "x": 934,
        "y": 339,
        "w": 492,
        "h": 142
    },
    {
        "id": "cb3b6c2a41cf72f0",
        "type": "tcp in",
        "z": "53d61a606f3a5b66",
        "g": "a4f8f71434887c90",
        "name": "监听11111",
        "server": "server",
        "host": "",
        "port": "11111",
        "datamode": "stream",
        "datatype": "utf8",
        "newline": "\\n",
        "topic": "",
        "trim": true,
        "base64": false,
        "tls": "",
        "x": 1020,
        "y": 440,
        "wires": [
            [
                "03818d515d781ad3",
                "42d9edb4e0b8039a"
            ]
        ]
    },
    {
        "id": "388fba5269805c57",
        "type": "tcp out",
        "z": "53d61a606f3a5b66",
        "g": "a4f8f71434887c90",
        "name": "",
        "host": "",
        "port": "",
        "beserver": "reply",
        "base64": false,
        "end": false,
        "tls": "",
        "x": 1350,
        "y": 440,
        "wires": []
    },
    {
        "id": "03818d515d781ad3",
        "type": "debug",
        "z": "53d61a606f3a5b66",
        "g": "a4f8f71434887c90",
        "name": "2",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1170,
        "y": 380,
        "wires": []
    },
    {
        "id": "42d9edb4e0b8039a",
        "type": "delay",
        "z": "53d61a606f3a5b66",
        "g": "a4f8f71434887c90",
        "name": "",
        "pauseType": "delay",
        "timeout": "15",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 1190,
        "y": 440,
        "wires": [
            [
                "388fba5269805c57"
            ]
        ]
    },
    {
        "id": "a24078b37786ab11",
        "type": "group",
        "z": "53d61a606f3a5b66",
        "name": "Semaphore",
        "style": {
            "label": true,
            "fill": "#ffffbf",
            "label-position": "n",
            "color": "#000000"
        },
        "nodes": [
            "2681cf6bfa3573b5",
            "2f6841c7c64868c8",
            "0e926bcd5e075db3",
            "84d8551b17812c30",
            "814d5508332656f4",
            "835bdced53074bb6",
            "eea944fcfdf24a06",
            "0afaf1f1096ceca4"
        ],
        "x": 794,
        "y": 139,
        "w": 692,
        "h": 162
    },
    {
        "id": "2681cf6bfa3573b5",
        "type": "function",
        "z": "53d61a606f3a5b66",
        "g": "a24078b37786ab11",
        "name": "semaphore",
        "func": "\n\nconst semaphore = context.get(\"semaphore\") || Semaphore(1);\ncontext.set(\"semaphore\", semaphore)\n\nif (msg.action === \"take\") {\n    const qmsg = RED.util.cloneMessage(msg)\n    delete qmsg.action\n    semaphore.take(qmsg, node.send)\n    updateStatus()\n} else if (msg.action === \"leave\") {\n    semaphore.leave()\n    node.send(msg);\n} else if (msg.action === \"clear\") {\n    semaphore.clear()\n}\n\nupdateStatus()\n\nreturn\n\nfunction updateStatus() {\n    if (semaphore.queue.length == 0) {\n        node.status({ fill: \"green\", shape: \"dot\", text: `empty` });\n    } else {\n        node.status({ fill: \"yellow\", shape: \"dot\", text: `Holding ${semaphore.queue.length}`});\n    }\n}\n\nfunction Semaphore(capacity) {\n    var nextTick = function (fn) { setTimeout(fn, 0); }\n    if (typeof process != 'undefined' && process && typeof process.nextTick == 'function') {\n        nextTick = process.nextTick;\n    }\n    var semaphore = {\n        capacity: capacity || 1,\n        queue: [],\n        take: function (data, callback) {\n            // node.warn([\"take\", semaphore])\n\n            var item = {\n                sent: false,\n                pos: semaphore.queue.length + 1,\n                task: function() {\n                    if(!item.sent) {\n                        callback(data)\n                        item.sent = true\n                    }\n                }\n            }\n            semaphore.queue.push(item);\n            if (item.pos <= semaphore.capacity) {\n                nextTick(semaphore.leave)\n            }\n        },\n\n        leave: function () {\n            if (!semaphore.queue.length) {\n                 return;\n            }\n            let item = semaphore.queue[0];\n            if (item) {\n                if(item.sent) {\n                    // node.warn([\"leave - shifting item\", item])\n                    semaphore.queue.shift()\n                    nextTick(semaphore.leave)\n                } else {\n                    // node.warn([\"leave - queing next execution task\", item])\n                    nextTick(item.task)\n                }\n            }            \n        },\n\n        clear: function () {\n            // node.warn([\"clear\", semaphore])\n            semaphore.queue = []\n            semaphore.current = 0\n        },\n\n        available: function (n) {\n            n = n || 1;\n            return (semaphore.current + n <= semaphore.capacity);\n        }\n    };\n\n    return semaphore;\n};\n\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1310,
        "y": 200,
        "wires": [
            [
                "835bdced53074bb6"
            ]
        ]
    },
    {
        "id": "2f6841c7c64868c8",
        "type": "link in",
        "z": "53d61a606f3a5b66",
        "g": "a24078b37786ab11",
        "name": "semaphore take",
        "links": [],
        "x": 900,
        "y": 180,
        "wires": [
            [
                "0e926bcd5e075db3"
            ]
        ],
        "l": true
    },
    {
        "id": "0e926bcd5e075db3",
        "type": "change",
        "z": "53d61a606f3a5b66",
        "g": "a24078b37786ab11",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "action",
                "pt": "msg",
                "to": "take",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1100,
        "y": 180,
        "wires": [
            [
                "2681cf6bfa3573b5"
            ]
        ]
    },
    {
        "id": "84d8551b17812c30",
        "type": "link in",
        "z": "53d61a606f3a5b66",
        "g": "a24078b37786ab11",
        "name": "semaphore leave",
        "links": [],
        "x": 900,
        "y": 220,
        "wires": [
            [
                "814d5508332656f4"
            ]
        ],
        "l": true
    },
    {
        "id": "814d5508332656f4",
        "type": "change",
        "z": "53d61a606f3a5b66",
        "g": "a24078b37786ab11",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "action",
                "pt": "msg",
                "to": "leave",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1100,
        "y": 220,
        "wires": [
            [
                "2681cf6bfa3573b5"
            ]
        ]
    },
    {
        "id": "835bdced53074bb6",
        "type": "link out",
        "z": "53d61a606f3a5b66",
        "g": "a24078b37786ab11",
        "name": "semaphore return",
        "mode": "return",
        "links": [],
        "x": 1445,
        "y": 200,
        "wires": []
    },
    {
        "id": "eea944fcfdf24a06",
        "type": "link in",
        "z": "53d61a606f3a5b66",
        "g": "a24078b37786ab11",
        "name": "semaphore clear",
        "links": [],
        "x": 900,
        "y": 260,
        "wires": [
            [
                "0afaf1f1096ceca4"
            ]
        ],
        "l": true
    },
    {
        "id": "0afaf1f1096ceca4",
        "type": "change",
        "z": "53d61a606f3a5b66",
        "g": "a24078b37786ab11",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "action",
                "pt": "msg",
                "to": "clear",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1100,
        "y": 260,
        "wires": [
            [
                "2681cf6bfa3573b5"
            ]
        ]
    }
]

Thanks for your comment. Even though I didn't test your demo, it looks not quite appropriate for my case. Although it is a good idea in other situations :slight_smile:

In my case, the TCP server closes the TCP connection once it returns the response immediately, so I can't separate the message with a special character. So the best option is to implement the net.Socket in function node to make sure each request will create a new TCP connection. Please advise me if my workaround has any concerns, thanks!

If you need it to close, a slight tweak resolves that...

[{"id":"2e2d787232b8ef60","type":"http in","z":"53d61a606f3a5b66","name":"","url":"/test","method":"post","upload":false,"swaggerDoc":"","x":740,"y":620,"wires":[["8c5fa82733fd8f02"]]},{"id":"2828b02abccf1a4f","type":"tcp request","z":"53d61a606f3a5b66","name":"","server":"localhost","port":"11111","out":"time","ret":"string","splitc":"0","newline":"\\n","trim":false,"tls":"","x":1270,"y":620,"wires":[["672f219c956939e4","7ee1f6c07bdd0146"]]},{"id":"8c5fa82733fd8f02","type":"function","z":"53d61a606f3a5b66","name":"add flag","func":"msg.flag = RED.util.generateId()\nnode.log(\"flag:\" + msg.flag + \",payload:\" + msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"crypto","module":"crypto"}],"x":900,"y":620,"wires":[["2eeb96fd0e4f4d91","93bf7d2106a6e741"]]},{"id":"672f219c956939e4","type":"function","z":"53d61a606f3a5b66","name":"print response","func":"node.log(\"flag:\" + msg.flag + \",payload:\" + msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1480,"y":620,"wires":[["f34b20e3b48bf779"]]},{"id":"e57a3876b7e6f0fc","type":"inject","z":"53d61a606f3a5b66","name":"test 3","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"3","payloadType":"num","x":810,"y":820,"wires":[["9c397614b000e13e"]]},{"id":"9c397614b000e13e","type":"function","z":"53d61a606f3a5b66","name":"make multiple messages","func":"for (let index = 0; index < msg.payload; index++) {\n    const m = {\n        payload: \"*\" + Date.now() + \"*\",\n        requestTimeout: 5000\n    }\n    node.send(m);\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1010,"y":800,"wires":[["9647b5cb32858609"]]},{"id":"9647b5cb32858609","type":"http request","z":"53d61a606f3a5b66","name":"","method":"POST","ret":"txt","paytoqs":"ignore","url":"http://192.168.1.61:1880/test","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"headers":[],"x":1230,"y":800,"wires":[["559855fe09055156"]]},{"id":"559855fe09055156","type":"debug","z":"53d61a606f3a5b66","name":"done (4)","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1420,"y":800,"wires":[]},{"id":"daf26c52e601f08f","type":"inject","z":"53d61a606f3a5b66","name":"test 1","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":810,"y":780,"wires":[["9c397614b000e13e"]]},{"id":"1583264947bb0274","type":"inject","z":"53d61a606f3a5b66","name":"test 50","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"50","payloadType":"num","x":810,"y":860,"wires":[["9c397614b000e13e"]]},{"id":"d5f96f761e5259be","type":"catch","z":"53d61a606f3a5b66","name":"","scope":["9647b5cb32858609"],"uncaught":false,"x":1050,"y":900,"wires":[["d8efe97e5f3574ee","ebcce6b128a29a4f"]]},{"id":"d8efe97e5f3574ee","type":"debug","z":"53d61a606f3a5b66","name":"err","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1210,"y":960,"wires":[]},{"id":"c42ffa50e3bfe661","type":"inject","z":"53d61a606f3a5b66","name":"clear","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":810,"y":1040,"wires":[["e0cc99a96593c366"]]},{"id":"2eeb96fd0e4f4d91","type":"link call","z":"53d61a606f3a5b66","name":"","links":["2f6841c7c64868c8"],"linkType":"static","timeout":"30","x":1080,"y":620,"wires":[["2828b02abccf1a4f"]]},{"id":"f34b20e3b48bf779","type":"link call","z":"53d61a606f3a5b66","name":"","links":["84d8551b17812c30"],"linkType":"static","timeout":"30","x":1710,"y":620,"wires":[["2dfcbf03c16f805b"]]},{"id":"7ee1f6c07bdd0146","type":"debug","z":"53d61a606f3a5b66","name":"3","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1470,"y":560,"wires":[]},{"id":"93bf7d2106a6e741","type":"debug","z":"53d61a606f3a5b66","name":"1","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1050,"y":560,"wires":[]},{"id":"e0cc99a96593c366","type":"link call","z":"53d61a606f3a5b66","name":"","links":["eea944fcfdf24a06"],"linkType":"static","timeout":"30","x":990,"y":1040,"wires":[[]]},{"id":"ebcce6b128a29a4f","type":"link call","z":"53d61a606f3a5b66","name":"","links":["84d8551b17812c30"],"linkType":"static","timeout":"30","x":1250,"y":900,"wires":[[]]},{"id":"2937e3e3e75775f3","type":"catch","z":"53d61a606f3a5b66","name":"","scope":["2e2d787232b8ef60","8c5fa82733fd8f02","2828b02abccf1a4f","672f219c956939e4"],"uncaught":false,"x":1510,"y":680,"wires":[["c486a51ba28cdf47","92ac7ce68a747a4b"]]},{"id":"92ac7ce68a747a4b","type":"change","z":"53d61a606f3a5b66","name":"","rules":[{"t":"set","p":"statusCode","pt":"msg","to":"500","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1720,"y":680,"wires":[["2dfcbf03c16f805b"]]},{"id":"c486a51ba28cdf47","type":"debug","z":"53d61a606f3a5b66","name":"err","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1670,"y":740,"wires":[]},{"id":"2dfcbf03c16f805b","type":"http response","z":"53d61a606f3a5b66","name":"","statusCode":"","headers":{},"x":1950,"y":640,"wires":[]},{"id":"a4f8f71434887c90","type":"group","z":"53d61a606f3a5b66","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["cb3b6c2a41cf72f0","388fba5269805c57","03818d515d781ad3","42d9edb4e0b8039a"],"x":934,"y":339,"w":492,"h":142},{"id":"cb3b6c2a41cf72f0","type":"tcp in","z":"53d61a606f3a5b66","g":"a4f8f71434887c90","name":"监听11111","server":"server","host":"","port":"11111","datamode":"stream","datatype":"buffer","newline":"\\n","topic":"","trim":true,"base64":false,"tls":"","x":1020,"y":440,"wires":[["03818d515d781ad3","42d9edb4e0b8039a"]]},{"id":"388fba5269805c57","type":"tcp out","z":"53d61a606f3a5b66","g":"a4f8f71434887c90","name":"","host":"","port":"","beserver":"reply","base64":false,"end":false,"tls":"","x":1350,"y":440,"wires":[]},{"id":"03818d515d781ad3","type":"debug","z":"53d61a606f3a5b66","g":"a4f8f71434887c90","name":"2","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1170,"y":380,"wires":[]},{"id":"42d9edb4e0b8039a","type":"delay","z":"53d61a606f3a5b66","g":"a4f8f71434887c90","name":"","pauseType":"delay","timeout":"15","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1190,"y":440,"wires":[["388fba5269805c57"]]},{"id":"a24078b37786ab11","type":"group","z":"53d61a606f3a5b66","name":"Semaphore","style":{"label":true,"fill":"#ffffbf","label-position":"n","color":"#000000"},"nodes":["2681cf6bfa3573b5","2f6841c7c64868c8","0e926bcd5e075db3","84d8551b17812c30","814d5508332656f4","835bdced53074bb6","eea944fcfdf24a06","0afaf1f1096ceca4"],"x":794,"y":139,"w":692,"h":162},{"id":"2681cf6bfa3573b5","type":"function","z":"53d61a606f3a5b66","g":"a24078b37786ab11","name":"semaphore","func":"\n\nconst semaphore = context.get(\"semaphore\") || Semaphore(1);\ncontext.set(\"semaphore\", semaphore)\n\nif (msg.action === \"take\") {\n    const qmsg = RED.util.cloneMessage(msg)\n    delete qmsg.action\n    semaphore.take(qmsg, node.send)\n    updateStatus()\n} else if (msg.action === \"leave\") {\n    semaphore.leave()\n    node.send(msg);\n} else if (msg.action === \"clear\") {\n    semaphore.clear()\n}\n\nupdateStatus()\n\nreturn\n\nfunction updateStatus() {\n    if (semaphore.queue.length == 0) {\n        node.status({ fill: \"green\", shape: \"dot\", text: `empty` });\n    } else {\n        node.status({ fill: \"yellow\", shape: \"dot\", text: `Holding ${semaphore.queue.length}`});\n    }\n}\n\nfunction Semaphore(capacity) {\n    var nextTick = function (fn) { setTimeout(fn, 0); }\n    if (typeof process != 'undefined' && process && typeof process.nextTick == 'function') {\n        nextTick = process.nextTick;\n    }\n    var semaphore = {\n        capacity: capacity || 1,\n        queue: [],\n        take: function (data, callback) {\n            // node.warn([\"take\", semaphore])\n\n            var item = {\n                sent: false,\n                pos: semaphore.queue.length + 1,\n                task: function() {\n                    if(!item.sent) {\n                        callback(data)\n                        item.sent = true\n                    }\n                }\n            }\n            semaphore.queue.push(item);\n            if (item.pos <= semaphore.capacity) {\n                nextTick(semaphore.leave)\n            }\n        },\n\n        leave: function () {\n            if (!semaphore.queue.length) {\n                 return;\n            }\n            let item = semaphore.queue[0];\n            if (item) {\n                if(item.sent) {\n                    // node.warn([\"leave - shifting item\", item])\n                    semaphore.queue.shift()\n                    nextTick(semaphore.leave)\n                } else {\n                    // node.warn([\"leave - queing next execution task\", item])\n                    nextTick(item.task)\n                }\n            }            \n        },\n\n        clear: function () {\n            // node.warn([\"clear\", semaphore])\n            semaphore.queue = []\n            semaphore.current = 0\n        },\n\n        available: function (n) {\n            n = n || 1;\n            return (semaphore.current + n <= semaphore.capacity);\n        }\n    };\n\n    return semaphore;\n};\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1310,"y":200,"wires":[["835bdced53074bb6"]]},{"id":"2f6841c7c64868c8","type":"link in","z":"53d61a606f3a5b66","g":"a24078b37786ab11","name":"semaphore take","links":[],"x":900,"y":180,"wires":[["0e926bcd5e075db3"]],"l":true},{"id":"0e926bcd5e075db3","type":"change","z":"53d61a606f3a5b66","g":"a24078b37786ab11","name":"","rules":[{"t":"set","p":"action","pt":"msg","to":"take","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1100,"y":180,"wires":[["2681cf6bfa3573b5"]]},{"id":"84d8551b17812c30","type":"link in","z":"53d61a606f3a5b66","g":"a24078b37786ab11","name":"semaphore leave","links":[],"x":900,"y":220,"wires":[["814d5508332656f4"]],"l":true},{"id":"814d5508332656f4","type":"change","z":"53d61a606f3a5b66","g":"a24078b37786ab11","name":"","rules":[{"t":"set","p":"action","pt":"msg","to":"leave","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1100,"y":220,"wires":[["2681cf6bfa3573b5"]]},{"id":"835bdced53074bb6","type":"link out","z":"53d61a606f3a5b66","g":"a24078b37786ab11","name":"semaphore return","mode":"return","links":[],"x":1445,"y":200,"wires":[]},{"id":"eea944fcfdf24a06","type":"link in","z":"53d61a606f3a5b66","g":"a24078b37786ab11","name":"semaphore clear","links":[],"x":900,"y":260,"wires":[["0afaf1f1096ceca4"]],"l":true},{"id":"0afaf1f1096ceca4","type":"change","z":"53d61a606f3a5b66","g":"a24078b37786ab11","name":"","rules":[{"t":"set","p":"action","pt":"msg","to":"clear","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1100,"y":260,"wires":[["2681cf6bfa3573b5"]]}]

chrome_BFKPPKKmvu

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.