Why this response.end(callback) is called two times? - javascript

I am working with node.js, where i see this res.end(callback) is not controlled. Please help me to get relevent answer.
const http = require('http');
const body = ' Appending text';
const server = http.createServer((req,res)=> {
res.write("Hello , I created my first server ");
res.end(body,afterend)
});
server.listen(2000);
console.log("server is up and running at 2000");
function afterend(){
console.log("response ended")
}
**console o/p:
server is up and running at 2000
response ended
response ended
expected console o/p:
server is up and running at 2000
response ended
**

That is normal. Infact the it's not the callback that's being invoked twice. It's the createServer method. Most browsers make a call to grab /favicon.ico. The console.log with req.url will show you what's happening
const http = require('http');
const body = ' Appending text';
const server = http.createServer((req, res) => {
console.log('Who is getting called here', req.url);
res.write("Hello , I created my first server ");
res.end(body, afterend)
});
server.listen(2000);
console.log("server is up and running at 2000");
function afterend() {
console.log("response ended")
}

Related

connecting two apps using socketIO

I have implemented a user interface to do some wizard of oz testing. I have a user-side page (Page A), and a second page, the wizard page (Page B). They use the same data and page B receives some information from page A to load the correct data. When the user asks questions on page A, the question is sent to page B, and an answer should be sent back to page A. The problem is that Page A is open on device A and page B is open on Device B (both are on the same server).
I am trying to implement the communication between page A and page B using socketIO. I searched for hours and didn't find a complete example of connecting two apps using socketIO. They usually open the same app in multiple windows. That won't help me. My understanding so far is that I should create a server for each app, and then have the two servers communicate with each other. What I have so far doesn't work and no communication is happening. What I have is as follow:
for page A (index.html):
I added a index.js server file:
// Import packages
const express = require("express");
const socketIO = require("socket.io");
const path = require("path");
// Configuration
const PORT = process.env.PORT || 3000;
//const INDEX = path.join(__dirname, 'index.html');
const INDEX = path.join(__dirname, 'index.html');
console.log("INDEX", INDEX);
//const WIZARD = path.join(__dirname, 'wizard.html');
// Start server
const server = express()
//.use((req, res) => res.sendFile(INDEX), (req, res) => res.sendFile(WIZARD))
.use((req, res) => res.sendFile(INDEX))
.listen(PORT, () => console.log("Listening on localhost:" + PORT));
// Initiatlize SocketIO
const io = socketIO(server);
var other_server = require("socket.io-client")('http://localhost:4000');
other_server.on("connect",function(){
other_server.on('message',function(data){
// We received a message from Server 2
// We are going to forward/broadcast that message to the "Lobby" room
io.to('lobby').emit('message',data);
});
});
io.sockets.on("connection",function(socket){
// Display a connected message
console.log("User-Client Connected!");
// Lets force this connection into the lobby room.
socket.join('lobby');
// Some roster/user management logic to track them
// This would be upto you to add :)
// When we receive a message...
socket.on("message",function(data){
// We need to just forward this message to our other guy
// We are literally just forwarding the whole data packet
other_server.emit("message",data);
});
socket.on("disconnect",function(data){
// We need to notify Server 2 that the client has disconnected
other_server.emit("message","UD,"+socket.id);
// Other logic you may or may not want
// Your other disconnect code here
});
});
For the same app, to the index.html I added the following script:
<script type="text/javascript">
// Get WebSocket
var socket = io.connect('http://localhost:3000');
// Client
socket.on('connect', function(){
socket.emit("message","This is my message");
socket.on('message',function(data){
console.log("We got a message: ",data);
});
});
// Join a channel
var room = "test";
socket.emit("join", room);
let msg = "hello helloo helloooo from index.html";
socket.emit("new_message", msg);
socket.on("new_message", function (msg) {
console.log("sending a message through server from index.html", msg);
});
</script>
For the second app, wizard.html I added a server file, index.js:
// Import packages
const express = require("express");
const socketIO = require("socket.io");
const path = require("path");
// Configuration
const PORT = process.env.PORT || 4000;
//const INDEX = path.join(__dirname, 'index.html');
const INDEX = path.join(__dirname, 'wizard.html');
console.log("INDEX", INDEX);
//const WIZARD = path.join(__dirname, 'wizard.html');
// Start server
const server = express()
//.use((req, res) => res.sendFile(INDEX), (req, res) => res.sendFile(WIZARD))
.use((req, res) => res.sendFile(INDEX))
.listen(PORT, () => console.log("Listening on localhost:" + PORT));
// Server 2
const io = socketIO(server);
io.sockets.on("connection",function(socket){
// Display a connected message
console.log("Server-Client Connected!");
// When we receive a message...
socket.on("message",function(data){
// We got a message. I don't know, what we should do with this
});
});
and to the wizard.html, I added the script below:
<script type="text/javascript">
// Get WebSocket
//var socket = io();
var socket = io.connect('http://localhost:4000');
// Join a channel
var room = "test";
socket.emit("join", room);
let msg = "hello helloo helloooo from wizard";
socket.emit("new_message", msg);
socket.on("new_message", function (msg) {
console.log("sending message through server from wizard", msg);
});
/*
*/
</script>
I also added <script src="/socket.io/socket.io.js"></script> to both apps, index.html, and wizard.html.
In wizard.html I get this error:
POST http://localhost:4000/socket.io/?EIO=3&transport=polling&t=OAp7bZr 400 (Bad Request)
and in index.html I get this error:
Access to XMLHttpRequest at 'http://localhost/socket.io/?EIO=3&transport=polling&t=OAp7k5w' from origin 'http://localhost:3000' has been blocked by CORS policy:
If you can help me figure out what I am missing or if you know of any complete working example similar to what I am trying to accomplish, I would very much appreciate it if you let me know.
It would be even more helpful if someone could use the code and scenario I provided here and write a minimum working example in which the two apps, a.html, and b.html, can communicate through socketIO.

NodeJS - where to place functions for eval()

I have a NodeJS-Server which communicated with the fronend via Websocket-Connection.
When the Server gets a on('message'), it should run a function which name is given the message via eval().
it workes fine, unless I completely don't know where to put the funcions to be called.
var http = require('http');
var ws = require('ws');
function render(vars) {
var server = http.createServer(function(req, res) {
.....
});
/* WEBSOCKET */
var wsServer = new ws.Server({server});
wsServer.on('connection', socket => {
socket.on('message', message => {
console.log('WS from template <-- ', message);
var wsIn = JSON.parse(message);
eval(wsIn.action);
});
});
}
when a message is incoming, eval(wsIn.action) should run a function called.. .lets assume runme.. so where would I now need to declare this function ? I try everything but whatever I do, i get
ReferenceError:: runme is not defined
edit:
I found out something interesting:
when i call a function normal like runme(); in my onMessage.. everything is cool.. but with eval(runme); nothing happens.. no error, no output, nothing..

Problems with sending data to HL7 server using node.js

I'm just trying to make a simple HL7 MLLP client using node.js
I made some code that creates connection with HL7 server via socket. It sends some data to server. Then it waits for some answer. For testing purposes I use HAPI TestPanel 2.0.1.
So, I have an issue. When I send data using my script to HAPI TestPanel, testpanel don't anwser me. In the testpanel's log it says that my client has connected to it and than nothing. When I turned on a debug option in testpanel, Log says that testpanel recieved bytes from my client, end then nothing else.
What is the wrong with my script?
Can anyone help me?
Thank you!
Here is my script:
const net = require('net');
const VT = String.fromCharCode(0x0b);
const FS = String.fromCharCode(0x1c);
const CR = String.fromCharCode(0x0d);
const clientOptions = {
host: '127.0.0.1',
port: 49360
};
const client = net.createConnection(clientOptions, () => {
var reqdata = 'MSH|^~\\&|HOSP|HIS|HOSP|PACS|20180104150804||ORM^O01|1|T|2.3\nZDS|1.2.398.7.1.1.2.494.0.1^^Application^DICOM';
reqdata = VT + reqdata + CR + FS + CR;
console.log(`${new Date()} connected to HL7 server!`);
console.log(reqdata);
client.write(new Buffer(reqdata, encoding = "utf8"));
});
client.on('data', (data) => {
var ansData = data.toString();
console.log(`${new Date()} HL7 answer data: ${ansData}`);
client.end();
});
client.on('error', (err) => {
var reqerror = `${new Date()} problem with request: ${err.message}`;
console.error(reqerror);
client.end();
console.log(`${new Date()} disconnected from HL7 server`);
});
client.on('end', () => {
console.log(`${new Date()} disconnected from HL7 server`);
});
Here is a screenshot of a testpanel's log:
Well, you are writing MLLP correctly:
reqdata = VT + reqdata + CR + FS + CR;
Though the first CR is not needed and following is OK:
reqdata = VT + reqdata + FS + CR;
But, the message that is received on HAPI Test Panel looks gibberish. The message is being HTML formatted somewhere. Review your code to keep it simple text.

Receiving API info after it responds to client (sending undefined instead of api info)

This is my node.js file, what's happening is, a user inputs an id and it gets sent to the server-side, which the server then takes and searches it through an api on a third-party. The problem I am having is, the response from the initial id sent by the user gets res.end before I get the info back from the api, thus getting a big fat undefined or an empty string on the client side. How can I make it so the res.end waits until it receives the data from the api and then sends it to the client? Or am I going at it entirely wrong and shouldn't be doing it this way?
var http = require('http');
var https = require('https');
var url = require('url');`
http.createServer(function (req, res) {
var id = url.parse(req.url,false).query;
var realId = getInfoFromApi(id);
res.setHeader('Access-Control-Allow-Origin', '*');
res.writeHead(200);
res.end(JSON.stringify(realId));
}).listen(3000, '127.0.0.1');
function getInfoFromApi(id) {
var url = "https://random.com/" + id + "?api_key=blabla";
var test = https.get(url, function(res) {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
var theId = JSON.parse(body)
console.log("Got response: ", theId);
});
}).on('error', function(e) {
console.log("Got error: ", e);
});
return test;
}
Any info into what I should be looking or resources that would help me would be greatly appreciated, thanks in advance for any help.
Also as a bonus question, should I be using POST method instead of GET from server to api-server? Or does POST privacy only matter from client to server? I'm just curious if clever clients would be able to access the server http.requests if I use GET instead of POST or if it even matters at all since it's from the server and not the client.
Oh and another thing, I was debating if I should use https.createServer since I have to use https for https.get, that way I could remove the http module from require and only use https. Is there any big difference in performance or anything if I do that?
Thanks again in advance.
EDIT:
http.createServer(function (req, res) {
var id = url.parse(req.url, false).query;
var link = "https://random.com/" + id + "?api_key=blabla";
var testo = https.get(link, function (rez) {
var body = '';
rez.on('data', function (chunk) {
body += chunk;
});
rez.on('end', function () {
var endRes = body
res.setHeader('Access-Control-Allow-Origin', '*');
res.writeHead(200);
res.end(endRes);
});
}).on('error', function (e) {
console.log("Got error: ", e);
});
}).listen(3000, '127.0.0.1');
I managed to change it like this after I read into callbacks. Thank you for that. It works fine now, so happy, thanks again. My question now though is, does this work flawlessly if dozens or hundreds of people are searching at the same time? Does each client connected to the server get their own seperate function thing that runs at their own pace without interfering with others? Thanks again for all your help.

Learning Node - Book - Pages 16-18 - Two Examples

There are two examples in between these pages 16 and 18.
Example 1.3 is a server app.
Example 1.4 is a client app doing GET requests to the server.
When I run the two examples (at the same time) I notice some quite weird behavior
in the client. All requests are executed (i.e. the for loop in the client completes)
but the callbacks of only 5 of them get called. The client doesn't exit and also
doesn't error out. And just no more callbacks are called.
Any ideas what might be happening or how I can troubleshoot this further?
Note: I am running Node.js v0.10.20 on Windows 7.
Server:
var http = require('http');
var fs = require('fs');
// write out numbers
function writeNumbers(res) {
var counter = 0;
// increment, write to client
for (var i = 0; i<100; i++) {
counter++;
res.write(counter.toString() + '\n');
}
}
// create http server
http.createServer(function (req, res) {
var query = require('url').parse(req.url).query;
var app = require('querystring').parse(query).file;
// content header
res.writeHead(200, {'Content-Type': 'text/plain'});
if (!app){
res.end();
console.log('No file argument found in query string.');
return;
}else{
app = app + ".txt";
}
// write out numbers
writeNumbers(res);
// timer/timeout to open file and read contents
setTimeout(function() {
console.log('Opening file: ' + app + '.');
// open and read in file contents
fs.readFile(app, 'utf8', function(err, data) {
res.write('\r\n');
if (err)
res.write('Could not find or open file ' + app + ' for reading.\r\n');
else {
res.write(data);
}
// response is done
res.end();
});
},2000);
}).listen(8124);
console.log('Server running at 8124');
Client:
var http = require('http');
var N = 200;
// The URL we want, plus the path and options we need
var options = {
host: 'localhost',
port: 8124,
path: '/?file=automatic',
method: 'GET'
};
var callback_function = function(response) {
// finished? ok, write the data to a file
console.log('got response back');
};
for (var i = 1; i <= N; i++) {
// make the request, and then end it, to close the connection
http.request(options, callback_function).end();
console.log('done with call # ' + i);
}
--- Experiment Done ---
If I lower N to 10 and also if I do a
global "var i = 1" and then do this thing:
function schedule(){
http.request(options, callback_function).end();
console.log('done with call ' + i);
i++;
if (i<=N){
setTimeout(function(){
schedule();
}, 1000);
}
}
schedule();
instead of the loop in the client, I get similar behavior.
I guess that's what Milimetric meant by "sleep" i.e. just
to make sure I don't hit the server too quickly with too
many simultaneous requests.
But the behavior is not fully identical, it takes several mins
to print 'got response back' on the second set of 5 requests
and then another maybe 5-6 mins for the client to exit.
Still, all that does look weird to me.
C:\PERSONAL\NODE_TEST>node test004.js
done with call 1
got response back
done with call 2
got response back
done with call 3
got response back
done with call 4
got response back
done with call 5
got response back
done with call 6
done with call 7
done with call 8
done with call 9
done with call 10
got response back
got response back
got response back
got response back
got response back
C:\PERSONAL\NODE_TEST>
The problem is that the client doesn't consume the response body sent by the server, so the connection remains (half) open and the http agent only allows 5 concurrent requests per client by default, causing it to hang after 5 requests. The connection will eventually timeout, causing the next 5 requests to be processed.
node.js http.get hangs after 5 requests to remote site
Change your callback function to consume any data sent down the response.
var callback_function = function(response) {
// finished? ok, write the data to a file
console.log('got response back');
response.on('data', function () {});
};

Categories