I am setting up a Client/Server communication between my tablet and my PC. My Client cant get any data from the server, what am I doing wrong.
My PC is running a Node.js server (using Express) and my tablet runs a client written in Node.js (using Express). I can access the server via the browser and get the data, but not through the javascript code.
My SERVER code is:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('App requested a connection');
});
app.listen(3000, () => console.log('Listening on port 3000!'));
app.get("/boxes", function (req, res)
{
//res.send(req.params[0]);
res.send("All boxes are in the basement");
});
My CLIENT code is:
const express = require('express');
const app = express();
console.log("Client working ...");
app.get("http://127.0.0.1:3000/boxes", function (req, res)
{
console.log("inside...");
console.log(res);
});
The CLIENT should return "All boxes are in the basement" and I get this when I use a browser but it doesn't work if I run the client code. The only message I get from client is "Client working ...".
Does anybody know what I am doing wrong?
Cheers
Express is a library for setting up and configuring an http server for incoming requests. It does not make outgoing requests to other servers. So, your client code is not a client at all.
Several problems here:
127.0.0.1 refers to your local device so your client is referring to itself when it uses 127.0.0.1.
In your client app.get("http://127.0.0.1:3000/boxes") is not a request for data. That attempts to set up an Express route for incoming requests as if you were declaring a second server. But, it's not even done correctly because you would only use the path there.
For a client to make a request of some other server, you would need to use a library call that actually does http requests. For example, you could do something like this:
Code:
const rp = require('request-promise');
rp.get("http://ipaddressOfServer:3000/boxes").then(data => {
// have response here
}).catch(err => {
// error here
});
I chose to use the request-promise library, but there are multiple different ways to make an http request. You can also use http.get() (lower level), request() (from the request library) or axios() from the axios library, etc...
Note, the computer your server is on (assuming it's running a desktop OS) will also have to probably turn of it's local firewall (e.g. windows firewall) or set up a specific rule to allow incoming connections on port 3000. Without that, the incoming connection will be blocked (for security reasons).
Related
Currently, we have a main server that is being hosted on localhost:3000 but to run our socket.io function, we need to run it on the same server. However, we need to run it separately (npm start separately). Is there a way to run it together or on the same server without it crashing?
You cannot run socket.io in a separate process, but on the same port as some other web server in some other process. The OS will not allow that as only one process can have a listening server on a specific port. If they are in the same process, that's easy as pie as socket.io is built to share an http server in the same process (one listening server internally, traffic divided between the two uses). But, not from separate processes.
To do that, you'd have to use something like nginx on your port 3000 to proxy plain web requests to one server on some other port say 3001 and socket.io requests to another server on some other port say 3002. The client would only deal with port 3000 and nginx would direct the traffic to the right server on different ports.
I'm thinking that when you say "npm start separately", you must have some other problem you're trying to solve with that statement and we could probably help with a better way to solve that actual problem (if you disclosed what that actual requirement is) while keeping socket.io and the http server in the same process and thus no need for a proxy to divide the traffic between two separate servers.
For example, you could start up your web server with no socket.io server started and then you could tell your web server process to start up the socket.io server later. Or you could start both the web server and socket.io server in the same process at initialization time, but have a temporary server configuration that blocks incoming socket.io connections until some other requirement is met.
But, without understanding what the real requirement is, you're just lobbing us an XY problem where you describe your attempted solution rather than the actual problem that needs to be solved. When we explain that your attempted solution is the wrong way to go, we need to know what the real problem is to help further.
This is simple SocketIo Server Code.
It's not a client code.
You have to download SocketIO at npm.
const express = require('express');
const http = require('http');
const SocketIo = require('socket.io');
const app = express();
app.set('view engine', 'pug');
app.set('views', __dirname + '\\views');
app.use('/public', express.static(__dirname + '/public'));
app.get('/', (req, res) => res.render('home'));
const handleListen = () => console.log('Listening on http://localhost:3000');
const httpServer = http.createServer(app);
const wsServer = SocketIo(httpServer);
wsServer.on('connection', (socket) => {
console.log('someone joined!')
socket.on('join_room', (roomName) => {
socket.join(roomName);
socket.to(roomName).emit('welcome');
});
});
httpServer.listen(3000, handleListen);
For more Info visit official documentation.
https://socket.io/get-started/chat
Lets say that i have a web server running on port 3001 and my ip is 23.512.531.56 (not an actual ip address btw) and i go onto another network, like my neighbours or something, if i type in chrome 23.512.531.56:3001why can i not get a response from the server? here is my nodeJS code.
//"Imports" libraries reqired.
const express = require("express");
const fs = require("fs");
//Starts express
const svr = express();
//Main
svr.get("/", (req, res)=>{
fs.createReadStream("./html/index.html").pipe(res);
});
svr.get("/image0.png", (req, res) => {
fs.createReadStream("./html/image0.png").pipe(res);
});
//Sets port to host on
svr.listen(3001);
You need to be in the same network. For example, if you are using different wifi (from your neighbors) you can't access your local NodeJs server. You can get to your server if your devices are under the same default gateway.
If you want to access it from any network, you might want to deploy it to a global network.
One thing to add, even for illustration don't use an IP address that is not right
You must open port 3001 to the outside and bind to your local machine (Port forwarding). Have a look into your router! And if it is not a fixed IP use a DynDNS service.
I'm using
nodejs in backend at localhost:3000
and
http Apache server at localhost:8080
$.post("http://localhost:3000", {data:"data"}, function(){alert("hurrah");});
// that one not working
$.get("http://localhost:3000", {data:"data"}, function(){alert("hurrah");});
// is working, but callback function not working
Have you checked out Cors for NodeJS?
Cross Domain requests may be blocked to your web server and if you're running NodeJS, you can add Cors(), configure the content you wish to accept (or accept all for the sake of debugging / time at the moment).
Depending on your NodeJS configuration you can set this up by including it at the top of your main class.
A default configuration, using Express might look something like this... (note this accepts all content!)
var express = require('express');
var app = express();
var cors = require('cors');
app.use(cors());
app.listen(8080, () => {
console.log('Listening on 8080');
});
I'm in the process of learning Node and have a question I can't seem to find the answer to. In the following example of a minimalistic chat server the node server expects the client page to reside in the same directory as the server file, if I was building a client side app for a mobile device, how would I send the data back to the proper client?
var fs = require('fs')
, http = require('http')
, socketio = require('socket.io');
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-type': 'text/html'});
**res.end(fs.readFileSync(__dirname + '/index.html'));**
}).listen(8080, function() {
console.log('Listening at: http://localhost:8080');
});
socketio.listen(server).on('connection', function (socket) {
socket.on('message', function (msg) {
console.log('Message Received: ', msg);
socket.broadcast.emit('message', msg);
});
});
Are you running into this problem? If so, perhaps using the phonegap iOS / Android plugins for WebSockets may help you.
For reference, here is what res.end(fs.readFileSync(__dirname + '/index.html')); means:
Synchronously read the contents of the file index.html (located in the server's current directory)
End the HTTP response after sending the contents of the file over the network to the client who requested the page (could be the local machine, a phone, a computer on the internet -- anyone who has access to the server). In other words, node is acting as an HTTP server for the page index.html
Index.html presumably contains some socket-related code that instructs the client to connect to the socket on the server (the server's socket is created by socketio.listen(server))
Based on the response to this question:
How do I configure nodejs/expressjs to serve pages over https?
I've been trying to set up the equivalent of:
var express = require('express');
var fs = require("fs");
var crypto = require('crypto');
var app = express.createServer();
var appSecure = express.createServer();
var privateKey = fs.readFileSync('privatekey.pem').toString();
var certificate = fs.readFileSync('certificate.pem').toString();
var credentials = crypto.createCredentials({key: privateKey, cert: certificate});
appSecure.setSecure(credentials);
app.get('/secretStuff', function(req,res) {
//redirect to https
}
appSecure.get('/secretStuff', function(req, res) {
//show you the secret stuff
}
Is this something that's doable with the current release of expressjs and node 2.4?
Yes, this can be done and it looks like you already have most of what you need. Just send the redirect in your app.get handler
app.get('/secretStuff', function(req,res) {
res.redirect('https://' + req.header('Host') + req.url);
}
Also make sure you do something like app.listen(80) and appSecure.listen(443) to actually start the servers on the appropriate port. Otherwise be sure to construct the HTTPS URL with the correct port. For production, this thing is typically handled outside of your app server (node.js) with a reverse proxy like nginx. It is trivial to do this in nginx which will let your node.js process run as non-root and remove the need to have clients directly connecting to node.js, which is not as battle-hardened as nginx for serving live internect TCP connections (I'm paraphrasing Ryan Dahl himself here).
You can only serve a web page over the connection that the request came in. If the request did not come in over https, you can't send the response that way.
So, first you have to be listening for both http and https requests. If a request comes in over http that you want to answer over a secure connection, do not do any processing but immediately redirect it to an https url. Then when the client reissues the request, process as normally.
If the framework uses JSGI then you can probably use the redirect module from Jack otherwise you will have to do it yourself. The details are at the link, i.e. response code 301 and Location: header with the https URL.