Tcp/in modes - what is the difference between connect to and listen to

Hi There,

I'm confused about a setup of nodes:

I have two tcp-in nodes one is listening on port 1234 (localhost) (the listener) and the other (the bottom one) is connected to port 1234 on localhost (the connector), i.e., the "connector" is connected to the "listener".

The change node sets the payload to 'ok' and passes that on to the tcp-out node in reply mode.

What I don't understand is the relationship between the two tcp-in nodes.

What happens when I trigger the inject button sending a payload of "hello world"? The debug 430 node joined to the "listener" receives "hello world", the debug 431 joined to the "connector" also receives "hello world".

So the tcp-out has connected to both and sent them both the message? Or has the "connector" sent the message to the "listener", having first received it from the tcp-out node? Or has the "listener", having received the message from the tcp-out node, sent the message to the "connector"?

Interestingly the "connector" (i.e. the bottom tcp-in node) also receives a second message with the "ok" payload from the change node. I.e., the "listener" sends message with a _session attribute to the tcp-out node and that session - it seems - represents the "connector" node.

I had a look at the code for a tcp-out node in reply mode and it seems that if not session is set, then all connections are sent a message and when a session is set, then only the corresponding session is sent a message. So it seems that the tcp-out node sends all connections in the connection pool a message if there is no _session attribute, i.e., the hello world message. The "ok" message is sent to the "connector" because .... the msg._session points to it? Because the message originated with the "listener" node, how come the "ok" message ends up with the "connector" node?

Then I tested the setup with a telnet session to port 1234. When I sent messages via telnet, they all came out on the debug 430, i.e., on the "listener". This seems a little inconsistent since, for me, the telnet is a type of tcp-out node so its message (from the telnet) should, I would have thought, gone to both tcp-in nodes. The "ok" messages generated by the tcp-out node only went to the telnet session, i.e., came back to telnet, it was not sent to the "connector" node. In fact the connector node received no messages when I use telnet.

Final question, is this setup an incorrect setup and something that should not be done? I mean I didn't have a use case, I just randomly put some tcp nodes together.

[{"id":"cdf9310b209c1838","type":"tcp in","z":"61cea49a1b24d505","name":"","server":"server","host":"","port":"1234","datamode":"stream","datatype":"utf8","newline":"","topic":"","trim":false,"base64":false,"tls":"","x":611,"y":567,"wires":[["922894e195cfced3","be8b10d81cf90c24"]]},{"id":"efcdb65d343c28d5","type":"tcp out","z":"61cea49a1b24d505","name":"","host":"","port":"","beserver":"reply","base64":false,"end":false,"tls":"","x":1000,"y":441.5,"wires":[]},{"id":"b19e4f202ce8e9f9","type":"inject","z":"61cea49a1b24d505","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"hello world","payloadType":"str","x":611,"y":444.5,"wires":[["efcdb65d343c28d5"]]},{"id":"922894e195cfced3","type":"change","z":"61cea49a1b24d505","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"ok","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":812,"y":502.5,"wires":[["efcdb65d343c28d5"]]},{"id":"dd0e889f20803d72","type":"tcp in","z":"61cea49a1b24d505","name":"","server":"client","host":"localhost","port":"1234","datamode":"stream","datatype":"utf8","newline":"","topic":"","trim":false,"base64":false,"tls":"","x":618,"y":711.5,"wires":[["0cad58dfd4a0f54e"]]},{"id":"be8b10d81cf90c24","type":"debug","z":"61cea49a1b24d505","name":"debug 430","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":859,"y":622,"wires":[]},{"id":"0cad58dfd4a0f54e","type":"debug","z":"61cea49a1b24d505","name":"debug 431","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":877,"y":842,"wires":[]}]

EDIT: ok, I think I understand it: the "connector" receives the hello world message from the tcp-out node. It sends it to the "listener", that then it sends back an "ok" to the "connector". But in fact that only works if the "connector" has its ouput set to "stream of strings", setting it to "single string" ensures that it procedures no output at all. (I'm not using delimiters with my strings.) Yet the listener then also receives the hello world message ... from the tcp-out node probably.

:rofl: Oh what a tangled web we sometimes weave!

This is not a "normal" configuration since you don't ever need to use TCP to communicate within a single Node-RED instance. Simply use link nodes which will be a lot more efficient of course.

I meant having two tcp-in nodes with one being in "connect to" mode and the other in "listen to" mode - what does it mean for a tcp in node to be connected to something? that something has to receive or generate messages to pass on to the "connect to" tcp in node. So I assumed that one could use the "connect to" tcp in node to "shadow" the "listen to" tcp in node so that messages are duplicated, i.e., the connect to tcp in node would reproduce the same messages that the listen to node would be receiving from connections to it.

But since there is little documentation, I thought I ask here. But it doesn't seem to be a much used use case - tcp in node in "connect to" mode.

Connect to connects “out” to another server - usually on another machine. Listen to listens to a local tcp port. Ie IS a tcp server.

Exactly but what happens if I connect a "connect to" to the local "listen to" node? The "connect to" node connects successfully to the "listen to" node, so it seems that they are connected and this is an ok thing to do.

If I then connect to the "listen to" node using telnet, then I can generate a message that the "listen to" node passes out as a message however the "connect to" doesn't generate any message even thought it is connected to the "listen to" node.

So how does a "connect to" tcp-in node generate messages?

When I use the tcp-out node which is configured in "reply to" mode in the flow, the "connect to" node generates a message, i.e., the inject node sends a message to the tcp-out node and the "connect to" node generates a message, along with the tcp-in node in listen-to mode.

I believe this behaviour is incorrect - that the tcp-out node in "reply to" mode can trigger a message from the tcp-in node in "connect to" mode. And having investigated, the tcp-out node in reply to mode will send a message to all connections in the connection pool if and only if the message does not contain a _session identifier. Why does it do that?

That's what I don't understand: why does the tcp-out node do that?

So that's the deeper issue that I'm thinking about.

EDIT: The reason I ask is because I want to implement the nodes in Erlang so I'm trying to understand their behaviours.

EDIT2: Another question: how do I close a session once it has been initiated? I.e., the telnet example from above: I telnet to an "listen to" node and now Node-RED should close the connection, how? I can reply to something using the tcp-out in "reply to" mode but how can I close the connection from inside Node-RED? ==> msg.reset sent to the tcp-out node in reply to mode

Yes it’s ok to connect them but they are both in (to NodeRED) nodes so won’t send messages to each other. The listen to node will listen to messages incoming to it eg your telnet and send them on.. as connections are session based ( ie we can have multiple clients connecting to the one listening port) it will tag the message with this so if you reply (via an out node) it will go back to the correct session - Or you can remove that tag to reply to all sessions.

The connect to node connects to a server, in this case localhost, and waits for it to output something which in this case has to come from a tcp out node.

1 Like

Got it - I can setup a tcp-out node that listens to port XYZ and at the same time, setup an tcp-in node that connects to port XYZ. I can then send messages to the tcp-out node and they arrive at the tcp-in node - ok, that's the behaviour I expected.

It was confusing to have a tcp-in now that can listen to a port and at the same time have a tcp-in node connect to it. Even though the tcp-in node in connect to mode has a status of "connected", it does not mean the same "connected" when its connected to a tcp-out node!

And I admit, it was a contrived example that should never have worked (i.e. two tcp-in nodes somehow connected to one another) but because things were connected, I assume something should happen!

Simplest analogy I can come with is you have plugged an earphone jack into a microphone socket. They will plug together physically but are both listening devices.

USB-C is rapidly becoming the same. I dunno what the Windows world is doing but modern Macbooks have incoming and outgoing USB-C ports, some are bidirectional, others aren't. Some are powered, others aren't. I can connect two chargers together and won't get twice as much power nor will I get electricity for free.