Streaming from NodeJS server not working when access from outside - node.js

I have a question about streaming an audio file via a NodeJS server. I'm using the following code:
var http = require('http');
var fs = require('fs');
var filePath = 'media/test.mp3';
var stat = fs.statSync(filePath);
http.createServer(function(request, response) {
response.writeHead(200, {
'Content-Type': 'audio/mpeg',
'Content-Length': stat.size
});
fs.createReadStream(filePath).pipe(response);
})
.listen(3000);
It does work when I ...
run it locally: http://localhost:3000 or
run it on a different machine in the same network: http://192.168.1.42:3000.
But it does not work when I ...
run it from outside, e.g. calling http://my-public-ip:3000 or
using a DynDNS service: http://my-dyndns-provider.com:3000.
By not working, I mean I can see a pending request ("request is not finished yet!") in Chrome devtools, but the stream sometimes starts only for less than a second, sometimes it doesn't start at all. In the devtools I can see that only 4 KB are loaded (on localhost it's 3.1 MB).
To enable the access from outside, I configured port forwarding on my router, so that requests to port 3000 are forwarded to my computer's internal IP.
For other things than streaming my setup is working, so for example it is possible to call REST routes defined on the server.
EDIT:
Meanwhile, I also tried to do the streaming with PHP instead of NodeJS. But it shows exactly the same behaviour.
Do you guys have an idea what could be the reason?
Thank you!

Looks like some configuration issue with setting up port forwarding in router as you have tried with two different code bases.
If you are doing only for testing you can use localtunnel to expose your localhost to publicly over the internet.
There are few other alternatives also like ngrock or forwardhq.
Hope it helps.

Yesterday, I finally was able to test the exact same setup but with a different router (FritzBox 7320) -- and everything worked as it should. So there must be problems with the router I'm using at home (o2 HomeBox 6441).
I think the best will be trying to get some support in the manufacturer board.
Thanks for your effort anyways!

Related

How to get Node.js http request to work from a browser on Siteground (shared hosting)?

Ok, I've searched around a bunch, and maybe the answer is here and I just couldn't find it because I wasn't using the right search combination or whatever, so please bear with me!
I'm very new to Node and all the tutorials I've read/watched (understandably) use localhost with a port number for examples. I'm having difficulty translating that into a real, shared-server website.
I successfully got Node.js installed on my shared hosting on Siteground (I can check versions, run javascript by pulling up node through putty, etc.).
I can start an http server using port 3000 and my ip address, and I can confirm that the server listener is working using another putty window and curl ipaddressORdomainname: 3000 (for testing purposes until I get it connected). I'm running the following to start the server:
const http = require('http');
const server = http.createServer((req, res) => {
console.log(req.url, req.method);
});
server.listen(3000, 'my_ip_address', () => {
console.log('listening for requests on port 3000')
})
And running curl ipaddressORdomainname: 3000 in another putty window successfully displays / GET in the other putty window with the open port.
What I can't seem to do is use any web browser (tried latest versions of Brave, Chrome, Edge, Firefox, Opera to no avail) to "connect" and show the same result I get from the curl line.
I'm ultimately trying to connect a website to the node.js server, and I think this is my final missing piece I can't seem to find a solution to.
Any guidance would be very appreciated.
Thanks!

Display text file using node js from a remote server

Good day! I'm having a hard time fixing this issue. I'm currently using node js webserver (http).
I'm a beginner in using node js so any help would be appreciated.
What I'm hoping to achieve is to display a string 'Hello World!' in the browser while accessing it through the URL. The problem is I'm running the script from a remote server and unfortunately I can't access it through the URL.
The script is running fine but for the browser it returns an error saying:
host didn’t send any data.
ERR_EMPTY_RESPONSE
Here is the script I'm running from the remote server:
var http = require('http');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('Hello World!');
response.end();
}).listen(2000);
I think my script doesn't have a problem. So I'm guessing it's from the setup of the server, but I don't have any idea in which part it's causing not to display it. I'm currently using a Linux Server.
Thanks in advance!
From what I can see you are listening on port 2000, are you sure that the url you are requesting the data from also contains the port e.g http://localhost:2000/ ?? Browsers by default tries to connect using port 80 on http and 443 for https, if you are listening on a different port than those, you have to define it in the url, by using a ":" after the domain/ip address
Anyway, have a look at the express module for server side rest APIs, will make request handling so much easier:
const express = require('express');
const app = express().listen(80);
app.get("/",function(request,response){
response.send('Hello World');
});
Express allows you to handle the creation of web servers better.
But node or express, do make sure that the URL you have entered consists of the port number that you have asked the server to listen to.
Another possibility is that the port you have asked to display your response is already being used by another server. You can try using a different port number.
You might have gotten the answer, but this is for the folks out there who are new to node at present and have stumbled upon this stackoverflow question! Good day :)

jsreport Hello world

I'm trying to create my first report with jsreport. I've followed the documentation, but I'm not able to generate the most simple Hello world.
I've tried:
npm install jsreport
and then create a simple server:
var http = require('http');
var jsreport = require('jsreport');
http.createServer(function (req, res) {
jsreport.render("<h1>Hello world</h1>").then(function(out) {
out.stream.pipe(res);
}).catch(function(e) {
res.end(e.message);
});
}).listen(1337, '127.0.0.1');
The server is running on port 1337.
But if I try to open http://localhost:1337/ nothing happens. I was expecting a page with Hello world.
On the server side, I get on the console:
2018-02-17T10:55:16.009Z - info: Initializing jsreport#1.10.0 in development mode using configuration file: jsreport.config.json
2018-02-17T10:55:16.011Z - info: Setting process based strategy for rendering. Please visit http://jsreport.net/learn/configuration for information how to get more performance.
2018-02-17T10:55:16.013Z - info: Searching for available extensions in /home/jgr/WebstormProjects/GeoMasterBoard/server/
2018-02-17T10:55:16.016Z - info: Extensions location cache not found, crawling directories
Do I need a jsreport server running or this code should be enough?
I also tried to install jsreport server, following the documentation.
After jsreport start it shows on the console:
2018-02-17T10:42:46.013Z - info: Initializing jsreport#1.10.0 in development mode using configuration file: jsreport.config.json
2018-02-17T10:42:46.015Z - info: Setting process based strategy for rendering. Please visit http://jsreport.net/learn/configuration for information how to get more performance.
2018-02-17T10:42:46.023Z - info: Searching for available extensions in /home/jgr/WebstormProjects/GeoMasterBoard/server/
2018-02-17T10:42:46.025Z - info: Extensions location cache not found, crawling directories
But nothing happens when I try to open http://localhost:5488/. If I do: nmap -p 5488 localhost the awnser is:
PORT STATE SERVICE
5488/tcp closed unknown
What am I missing?
I'm using node.js v8.1.2, on Ubuntu 16.04.
your code is not working because the following reasons:
when you open your browser at http://localhost:1337/ your browser is actually making 3 different requests (1-> http://localhost:1337/, 2-> http://localhost:1337/favicon.ico, 3-> http://localhost:1337/robots.txt), not just one
the code that your are using to handle the http server is not doing a proper routing, it should process a url just once, right now it is just calling jsreport.render on every single request that goes through your server (even the ones for /favicon.ico, /robots.txt), and this is bad in the browser because as i already explained your browser makes like 3 request for a single page load.
you are using the shortcut jsreport.render in the request handling, which means that jsreport is going to try to initialize itself when your first request arrives, because of the problem explained above (not doing a proper routing in your http server) this results in jsreport trying to initialize 3 times on your first page load which leads to an uncaught exception that exits your process with no error message (we are going to update some things to better handling this exception in the future).
finally, here is some code that completes your hello world test case (with some code that filters unwanted requests like /robots.txt, /favicon.ico, but in production code you should implement a proper router logic in your http server. if you don't want to code it yourself just use something like express)
var http = require('http');
var jsreport = require('jsreport');
http.createServer(function(req, res) {
if (req.url !== '/') {
return console.log('ignoring request:', req.url);
}
console.log('request:', req.url);
jsreport
.render('<h1>Hello world</h1>')
.then(function(out) {
out.stream.pipe(res);
})
.catch(function(e) {
res.end(e.message);
});
}).listen(1337, '127.0.0.1');

Node - Express -App does not respond to other servers

On Virtual Machine 1 I have a very simple node script
// server.js
var express = require('express');
var annotations = require('./routes/annotations');
var cors = require('cors');
var app = express();
app.use(cors());
app.options('/annotations/:id', cors());
app.get('/annotations/:id', annotations.findById);
app.listen(80, function() {
console.log('Server running');
});
When I access with the browser or curl from my local machine http://example.com/annotations/5770dffb2dc30a7433c729f7 I get instantly the correct data.
But when I try to it from Virtual Machine 2 with a PHP script (file_get_contents or curl), with CURL or even with w3m I cannot access it. PHP and CURL are trying it for long time and then run finally into timeouts, w3m says
Can't load http://example.com/annotations/5770dffb2dc30a7433c729f7.
I am loosing my mind! Any suggestions?
I suppose the issue is the network, not node. Please check if you can
ping 10.55.55.111
from your 2nd VM, assuming that your first VM's IP address running node is 10.55.55.111. If that fails, you have a network problem.
Two possible solutions:
Your two VMs are on different subnets. A great article about VM network adapters can be found at https://www.vmware.com/support/ws4/doc/network_configure_ws.html.
Maybe your first virtual machine has a "Host-only" network? You might need to set the virtual adapter to "Bridged" instead. Further explanation of "Host-only" and "Bridged" network adapters is given at http://slopjong.de/2013/05/14/virtualbox-make-your-virtual-machine-accessible-from-your-host-system-but-not-from-the-local-network/.

Meteor: How to get the hostname, server side

On the client I can use window.location.hostname to get the hostname. How can I get the same on the server?
I need this to work behind an Apache proxy, unfortunately Meteor.absoluteUrl() gives me localhost:3000. I also want it to work for different domains, I want one Meteor app that gives different results for different domains.
This question is somewhat related: Get hostname of current request in node.js Express
Meteor.absoluteUrl() given that your ROOT_URL env variable is set correctly.
See the following docs: http://docs.meteor.com/#meteor_absoluteurl.
Meteor doesn't know the outside-facing address of the proxy that it's sitting behind, and the (virtual) domain that this proxy was accessed by would have to be forwarded to the Meteor app for it to do what you are asking for. I don't think this is currently supported.
According to this you can now get the Host header inside Meteor.publish() and Meteor.methods() calls by accessing:
this.connection.httpHeaders.host
Elsewhere in the application, it's probably difficult to determine the Host header that is being used to connect.
If you want the hostname of the server, as configured in /etc/hostname for example:
With meteorite:
$ mrt add npm
In your server code:
os = Npm.require('os')
hostname = os.hostname()
This has no connection to the Host header provided in the incoming request.
updated answer with some of chmac's words from the comment below
In any server-side meteor file you can add:
if (Meteor.isServer) {
Meteor.onConnection(function(result){
var hostname = result.httpHeaders.referer; //This returns http://foo.example.com
});
}
You can fetch host as EnvironmentVariable from DDP object in method and publication. Meteor accounts-base package fetch userId via this way.
const currentDomain = function() {
const currentInvocation = DDP._CurrentMethodInvocation.get() || DDP._CurrentPublicationInvocation.get();
return currentInvocation.connection.httpHeaders.host;
}

Resources