Http response node msg.res and msg.req

Hi all

I have a project with multiple flows. I have a http in node on flow one and then I need to do some work on another flow and then only when the work is done, do I respond with the http response node.

So, if I respond without leaving the current flow, all works as expected. When I though respond from another flow or even the same flow after spending time in one or more other flows, I have no response object for the http response node.

I managed to get past it by creating a global context with the msg.res and msg.req values that I can then use later on to respond, but I do not feel that this is the right way of doing it. I also suspect that at some time I might start getting issues, because the global context might get so big, that I might start getting memory issues.

Can you maybe suggest a better way of doing this or at the least maybe help me to clear the global context value after I do not need it anymore?

I attach s screenshot of the first flow.

Regards
Morne

Generally, HTTP is used for an immediate response rather than a delayed response.

The "normal" way for Node-RED would be to make use of websockets which is designed for ongoing data exchange.

You can use the websocket node along with http-in/out but you may find it more convenient to use uibuilder (or Dashboard if you are happy with its layout) since that does everything together.

Hi

Maybe I must elaborate a bit more on what I am trying to achieve. I am building the business logic portion of a Radius AAA solution. A radius client will via UDP send Authorize and Accounting packets to Freeradius abd then Freeradius will via it's REST mod send an HTTP request to my /authorize http in node.

I must then do quite a bit of logic where I must check if the user exists, generate IP addresses etc and then respond back to Freeradius with reuiqred attribute value pairs.

So, the uibuilder or dashboard does not play a role here. I am also trying to work out how to use websockets with http in this scenario.

Regards
Morne

OK, then you cannot respond with an http-out node until you have completed your processing. However, the processing has to be fast enough so that the requesting client doesn't time out.

You can only have a single out for an in.

If you need to gather other information to forumulate a response, it must be done in a single flow I think.

Sometimes getting the response requires some other async action to be performed first. If that's a call to another HTTP endpoint, then the HTTP Request node makes it easy to do that async work 'inline' of the HTTP In/Response flow.

The challenge here is trying to do that async work via something like MQTT or UDP that doesn't provide built-in request/response semantics that a flow can block against.

@msupra I can't point you at a specific recipe for this pattern, although it would be worth us producing one.

As a general point of guidance, I'd use the Join node the block your HTTP-In flow until a response comes back from the flows you need to invoke in parallel. The trick will be to ensure the right msg.parts properties are set so the Join node can associate the right response with the right HTTP message.

Yes, the processing is fast enough, average response time is 32ms, so not a problem.

My flows work as expected, I just do not think it is the right way of making sure that the msg.res and msg.req is available for responding back to the client.

I feel that there must be abtter way of doing it.

Regards
Morne

Hi @knolleary

Thanks for the response. You are correct, there are multiple actions that need to be performed before I can respond back. I originaaly wanted to pass the msg.res and msg.req on via mqtt, but that failed, as the payload was too big for mqtt to handle properly.

I do not really want to block the http in flow, as I am expecting to be handling a very high load, so blocking to wait for response, might cause a bottlenect, that is if I understand your suggestion correctly.

Since my solution is working, I then only have one more concern regarding the size of the global context I use. Is there a way to remove the value I set and then later get from the context, as to minimize the growth of the context?

If I have thousands of clients connecting and there is a value in the global context the enormous size of the msg.req and msg.res, I assume that at some stage I am going to run into memory problems.

Is this assumption valid?

Regards
Morne

You are right of course and I badly worded that. All I was trying to get across there was that the client that requested the URL will be waiting for a single response and will only wait for a limited amount of time before it gives up. Clearly, the OP knows that though :slight_smile:

"Blocking" means the message from the HTTP In node sits at the Join node and doesn't carry on until the other work you want done has completed. It doesn't mean the runtime is blocked and stops doing anything - messages continuing flowing through.

The reason you cannot send req/res over MQTT is that they include handles to the raw TCP socket that the HTTP request is being handled on.

If you store them in global context, you are responsible for tidying them up. Also, you must make sure each request is stored under a unique key name as you don't want requests overwriting each other.

I'd recommend investigating the Join node approach. If I get a chance, I'll see if I can knock up an example of it. But no guarantees if I'll get to that today.

Yes, I am ensuring that I store it under a unique key, so that is handled. I just do not know how to clear the key from the context, when I am done with it.

I will also start investigating the join node.

Thanks for everyones assitance, I appreciate it.

You could add a node alongside the HTTP Response node that deletes the appropriate context value given the response has now (or is just about to be...) sent

Lol, that is unfortunately where I fall out of the bus. I found info on setting and getting, but I could not find anything on deleting/removing. Can you maybe help me with the code to use to delete the context value?

To delete a context value, set it to undefined

1 Like

Fantastic, thanks.

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