Http Server without response.end in Node js - javascript

I am having some confusion regarding the response.endin Node js, I have the following code.
const http = require("http");
http.createServer(function(req, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
setInterval(() => {
response.write(new Date() + "\n");
}, 1000)
}).listen(8080);
console.log("Service Running at 8080 127.0.0.1")
Now this above code will start printing the date in the browser after 20 seconds or more, now this code doesn't have any reponse.end, and it's obvious because if there was any response.end() then the code inside the setIntervel would never execute.
But doing this doesn't do anything it takes forever to load the page.
const http = require("http");
http.createServer(function(req, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write("Test");
}).listen(8080);
console.log("Service Running at 8080 127.0.0.1");
But if i add response.end in the above code it will work just fine.
So can anyone explain this weird behavior, that why using setInterval without response.end works.

What you signal as a problem is literally what should happen. The browser asks the server for data, the server starts sending data and never signals an "okay I am done" so that the browser knows the message is done.
The problem here is your idea on how to get data into the browser from the server.
Set up a websocket connection so you can push data from the server to the browser. That's what it's for. Or,
Set up a repeating call in the browser using setTimeout or setInterval or something, and just call the server every second or something, with the server responding with tiny, tiny messages that all actually end.

Related

How the request response cycle in node js works with external I/O

Complete node.js beginner here. I saw this "hello world" example somewhere
// Load the http module to create an http server.
var http = require('http');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Hello World\n");
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);
// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");
Really simple code in which the server responds to HTTP requests with a simple HTTP response with plain text "Hello World"
I also ready about a library to make HTTP requests from javascript
http.get(options, function(resp){
resp.on('data', function(chunk){
//do something with chunk
});
}).on("error", function(e){
console.log("Got error: " + e.message);
});
Here you make an HTTP request with some options and then do something with the response in a callback.
If one was to make such an API request when an HTTP request comes to the node.js server, what happens? Since the flow has to be single threaded, how can one change the state of the response node.js sends to the client in the callback of the HTTP API request? Won't the response be sent to the event loop already by then? How can one simulate synchronous requests in this system so that you can use the response of the API request to send a response to the client?
Since the flow has to be single threaded, how can one change the state of the response node.js sends to the client in the callback of the HTTP API request?
Because the response isn't sent synchronously with the request having been received.
Won't the response be sent to the event loop already by then?
The response isn't sent until you call res.send or similar, which doesn't have to be in the same job from the job queue that triggered your request callback — and frequently isn't.
How can one simulate synchronous requests in this system so that you can use the response of the API request to send a response to the client?
There's no need to, and doing so would kill throughput.
On any given thread (and NodeJS uses only one), JavaScript works on the basis of a job queue: The single JavaScript thread works by picking up a job from the queue, running the code for it all the way through, and then picking up the next job from the queue (or idling until one is added). When an event comes in or similar, if you've set up a handler for that event, a call to your handler is added to the job queue. (There are actually at least two layers to the job queue; see this answer for more on that if you're interested.)
It's absolutely fine if you don't respond to the "We got an HTTP request" from within the code for the job that called your handler. That's perfectly normal. The job and the request are completely disassociated from each other. And so it's fine (and normal) if you start an asynchronous process (like a get, or a readFile). Later, when the result of that process is available, a new job gets added to the queue, the JavaScript thread picks it up, and you use res.send or similar to reply to the request that's been waiting.
This is how NodeJS manages high throughput despite having only a single thread: If you use asynchronous I/O throughout, your actual code doesn't have to occupy the thread for all that long, because it doesn't wait for the I/O to complete. It can do more work on other things while the I/O is pending, and then respond to it when the I/O completes.
You need to change your code like this:
http.get(options, function(resp){
resp.on('data', function(chunk){
resp.send(chunk);
});
}).on("error", function(e){
console.log("Got error: " + e.message);
});

How to make a jQuery request to a locally hosted node.js server?

I have a simple node.js server saved in a file called server.js, the code for which is below:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8010);
I am running this locally in command line (with node.js installed) by executing
node server.js
If I then access this in my browser (google chrome) with the URL my.local.IP.address:8010 it displays hello world successfully.
I am also creating a webpage that will execute this jQuery as soon as the page is loaded:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
$.get("http://my.local.IP.address:8010/", function(){
alert("Success");
}).fail(function(err){
alert("Failed");
alert(JSON.stringify(err));
});
});
</script>
When I open this html file in my browser it always creates an alert box saying failed followed by this stringified JSON object as the error (I've formatted it so it is easier to read):
{
"readyState": 0,
"status" : 0,
"statusText": "error"
}
This happens no matter how many times I've tried while the node.js server is running locally. I have also tried to make an async XMLHTTP request function that does it myself, and this does not work either.
I know both the jQuery and the XMLHTTP function I made work correctly since if I call the functions on the URL https://httpbin.org/get it will return successfully.
Any ideas as to where I have gone wrong?
It's a cross domain issue. Browser thinks your page is not part of http://localhost:8081 server. You need to change server code as follows in order to make it work.
http.createServer(function (req, res) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8010);
I guess it may be a cross domain issue, as you are using your IP address in the call, and localhost:8010 on the browser url to access your site. It is a problem common to ajax requests, and has nothing to do with Node.js
Try using the same url to access the site than the one you are targeting to.
See this similar issue with cross domain

How to create a node.js server?

I'm trying to create my first node.js server and I have some problems.
When I use
var http = require("http");
var server = http.createServer();
server.listen(8888);
No connection can be established to the server.
But when I use this
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8888);
The server lands ok.
I used this in a file called server.js and runned the command node server.js. I'm using v 0.12.0
What am I missing? Why the server doesn't work on the first case?
The first block of code creates a server and listens on a port.
When you point a browser at it, the browser makes a request and then waits for a response.
You haven't told the server what to respond with, so it sits there doing nothing.
Eventually the browser times out.
In the second set of code, you've told the server how to respond to requests.

HTML code from node js not interpreted as such by the browser

I have created my first node js application: a simple webserver.
Here's the code:
// Load the http module to create an http server.
var http = require('http');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("ARD Tagesschau\n");
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);
// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");
When I connect to the server via my browser I get the full string specified in my code as a web page.
Shouldn't the browser interpret that HTML code and display a link? Why do I get the full HTML code shown as plain text?
You have explicitly said that you are returning plain text, not HTML. The browser therefore treats it as plain text.
If you want HTML to be treated as HTML then say it is HTML:
{"Content-Type": "text/html"}
(Although you should send back an HTML document and not a fragment of HTML).
Following Code works for me:
var http = require('http');
// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/html"});
response.end("ARD Tagesschau\n");
});
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);
// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");
You need to set the Headers. For more information check in Node API docs here.
Check the difference in your firebug or dev tools to understand how browser interprets differently based on Header Content-Type.

Node.js and web-socket-js simple client server not opening

My server.js seems to be correct..
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, "mysite.com");
console.log('Server running at mysite.com:1337/');
The meat of my client is below.
function init() {
// Connect to Web Socket.
// Change host/port here to your own Web Socket server.
ws = new WebSocket("ws://mysite.com:1337");
// Set event handlers.
ws.onopen = function() {
output("onopen");
};
}
If I go to http://www.mysite.com:1337 I correctly receive Hello World! However, when I try to connect using my client, and debug in Fire bug, I get the following output.
[WebSocket] connected
[WebSocket] request header: GET / HTTP/1.1 Upgrade: WebSocket Connection: Upgrade Host: mysite.com:1337 Origin: http://www.mysite.com Cookie: Sec-WebSocket-Key1: 115 17 p^!x-93 IERc16 7 Sec-WebSocket-Key2: 1 75 7Z i `. 8u $l031 4j9
[WebSocket] sent key3: ±Ôñ<g
[WebSocket] closed
And the WebSocket is automatically closed before I have any chance to do anything. Can anyone please shed some light on the error I am receiving and what do you think I should do?
You have created a node.js HTTP server but you are trying to connect to it as a WebSockets server. The WebSockets protocol is not plain sockets and it is not plain HTTP request. WebSockets have an HTTP like handshake but after that you have a full-duplex connection (like sockets and unlike HTTP) that has a small amount of message framing (unlike plain sockets).
Try using Socket.IO or node-websocket-server if you want to create a node.js WebSockets server. On the other hand if you are wanting to connect from Javascript to a regular HTTP server then use one of the great Javascript libraries with AJAX support such as jQuery.

Categories

Resources