Connecting to a Reliable Webservice with Nodejs - node.js

My application needs to receive a result from Reliable Webservice. Here is the scenario:-
First I send a CreateSequence request. Then the server replies with a CreateSequenceResponse message. Next I send the actual request to the webservice.
Then the webservice send a response with 202 accept code and sends result in a later message. All these messages contain the header Connection: keep-alive.
I made request with http.ClientRequest. I could capture all responses except the result. http.ClientRequest fires only one response event.
How can I receive the message which contains the result?
Is there any way to listen to socket for remaining data (socket.on('data') did not work). I checked this with ReliableStockQuoteService shipped with Apache Synapse. I appreciate if someone can help me.

When you get the response event, you are given a single argument, which is an http.IncomingMessage, which is a Readable stream. This means that you should bind your application logic on the data event of the response object, not on the request itself.
req.on('response', function (res) {
res.on('data', console.log);
});
Edit: Here is a good article on how to make HTTP requests using Node.

Related

When is Node http request actually fired?

Is node http request actually fired after req.end or after http.request ?
Context: I am using node js http module and wanted to understand what happens between:
var req = http.request(options)
// Register handler events
req.end();
Can node open socket and start dns look up before req.end() Or req.end() is to just suggest that no more data needs to be sent ?
From documentation "With http.request() one must always call req.end() to signify the end of the request - even if there is no data being written to the request body." I am not sure what to make out of this ?
Is node http request actually fired after req.end or after http.request ?
http.request() returns an instance of the http.ClientRequest class and the ClientRequest instance is a writable stream. Therefore, the request will be fired after req.end()
Can node open socket and start dns look up before req.end() Or req.end() is to just suggest that no more data needs to be sent ?
The answer for your question is no, the socket will be created after you sent the request, as mentioned before when you use req.end().
From documentation "With http.request() one must always call req.end() to signify the end of the request - even if there is no data being written to the request body." I am not sure what to make out of this ?
I think you should try to understand a little more about node streams. When you invoke the request method from http, it returns a writable stream, that means the request is "available" to be written. When you do the .end() you are telling to that stream that no more writing is needed, in other words, you don't need to build the request anymore and so the request is sent.

How to receive the result after sending data via WebSocket

Using ws package from npm you can do something like that:
const ws = new WebSocket('ws://localhost:9003');
ws.on('open', () => ws.send('rcon_password PASSWORD'));
ws.on('message', result => console.log(result));
If server expects client to send password then returns authentication result, how can i check result sent by server?
In Python you could do something like:
async with websockets.connect('ws://localhost:9003') as websocket:
await websocket.send('rcon_password PASSWORD')
result = await websocket.recv()
Client can send other commands later. How to relate data sent with ws.send() with those sent to another function in the event onmessage?
The webSocket protocol itself has no concept of a response to a message you send. And, because Javascript is event driven, you can't just block waiting for the response). So, the server just needs to send a message back to the client and the client needs to have a handler for incoming messages and handle the response appropriately when it arrives. If you need to make sure it's a response to THE specific message you previously sent to the server, then you can include some sort of messageID (that you coin yourself) when you send the first message and include that same messageID in the server response.
If you step up to the socket.io library for both client and server (which runs on top of the webSocket transport), then it has built-into it the concept of a response to your message. When sending your message, you just register a callback that gets called when the response comes back and the server has to handle its side appropriately to trigger the response callback on the client.

Is there good standard way to simulate Req/Res over Websocket?

I'm building my app entirely over websocket. While I see benefit of being able to send data to client without having client to request data to me. There are still benefits to req/res type of interaction as you can put all logic together.
Ex:
Take registration. You send data, server sends a OK or ERROR if something is wrong.
Right there it's three events! DataFromClient, RegistrationFailed, RegistrationSuccess. But with REST I could have made one POST request and handle if else in one function.
It shouldn't be too hard to create a library that allows you do to push notification + Req/Res type of interaction. It'd be even better if routes could be defined like express routes.
There is no "standard" way to implement request/response with webSocket. It is not part of the webSocket standard. It can certainly be done (more below on this), but there is no "standard" way of doing it.
The socket.io library which is built on top of webSocket has a response option built into any message it sends.
The sender does something like this:
socket.emit("msgName", someData, function(data) {
// data is the "response" to sending this message
console.log(data);
});
The recipient of a message that is expecting a response does something like this to cause the response to be sent:
socket.on("msgName", (someData, fn) => {
// send response
fn(someOtherData);
});
You could implement your own response scheme in webSocket. You'd have to add to your data format a uniqueID for each request so you could send that same uniqueID back in the response so the receiver would know which response belongs with which request.

why subsequent HTTP requests

My JavaScript makes that ajax call which retrieves a JSON array.
I am trying simulate long running HTTP REST call request that takes longer to return the results.
The way I do it is delay writing anything to the response object on the server side until 5 minutes elapsed since the request landed. After that I set the status to 200 and write the response with the JSON ending the stream.
Putting a breakpoint on the serve side I realize that the request shows up second time but the browser's Network tab does not show another request being made.
It may not be relevant but I am using browsersync middlewars to serve this JSON and write the bytes and end the response in setTimeout().
setTimeout(()=> {
res.statusCode = 200;
res.write(data);
res.end();
});
Question:
Anyone has any explanation as to why this is happening ? And if there is a way to simulate this in another ways ?
In most cases the browser should retry if connection is closed before response. This is a link to the details => HTTP spec Client Behavior if Server Prematurely Closes Connection
BTW it might help you use the chrome throttling options on the network section of dev tools (F12)

Are responses to HTTP requests required?

I think it's a generally applicable question, but this is what I'm trying to do: small Node.JS app that receives a POST request from GroupMe whenever a message is posted in a group to trigger and fulfills a completely separate action. They state that the callback URL will receive an HTTP POST request from us every time a message is published to that group. It doesn't make much of a difference to me if I need to respond to the POST, but I was curious if it's even necessary or if it had any negative implications.
var server = http.createServer(function(request, response) {
doStuff(request);
});
It really depends what you're doing, but generally if no response is sent then applications or users which expect there to be one will wait until the connection times out, which may take up to a minute or longer, get a time out error and assume your service doesn't work.
You don't have to send any text, just a HTTP response code will do. Have doStuff() return whether it was successful and send the appropriate code based on it:
var server = http.createServer(function(request, response) {
response.send(doStuff(request) ? 200 : 400);
});
200 means OK, 400 means Bad Request
What I know in the field of HTTP request and response, You should at least say response.end().
If you won't say response.end client will be waiting for response. So better to say a response.end after tour task.
var server = http.createServer(function(request, response) {
doStuff(request);
response.end(); //It tells browser/client that server has finished it's work on this request.
});

Resources