Trying to get node.js app to work on cPanel - javascript

I followed a tutorial on YouTube that shows how to make a node.js server that works with sockets.
Here is the final working server.js code.
var express = require('express');
var app = express()
var server = app.listen(3000)
app.use(express.static('public'))
console.log('My sockets server is running.');
var socket = require('socket.io')
var io = socket(server)
io.sockets.on('connection', newConnection)
function newConnection(socket) {
console.log('new connection: ', socket.id)
socket.on('send-msg', data => {
console.log('send-msg');
socket.broadcast.emit('send-msg', data)
})
}
This code works when I host it on my local server (http://localhost:3000/). Now I am trying to get it to be online using cPanel, I got the libraries set up correctly (I think) and I am using the same code, but it's not working. I'm just getting Cannot GET /mychat poping up in the display.
I tried making some changes:
...
const hostname = '[the ip address of my server]';
const port = 3000; // also tried port 22, same issue
var app = express()
var server = app.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
...
But I get the same issue.
When cPanel first created the server.js file, it made this code:
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
var message = 'It works!\n',
version = 'NodeJS ' + process.versions.node + '\n',
response = [message, version].join('\n');
res.end(response);
});
server.listen();
which does it's job, but it doesn't help me.
Here is the basic structure of the site:
root
- package.json
- package-lock.json
- server.js
> node_modules (folder with all of the required files including express and socket)
> public
- index.html
- script.js
- styles.css

You have to define the path and the directory, so the server can receive and send an Httpresponce. For the main directory it would be:
app.get('/' (req, res) => {
res.send('Home page')
});
In this case the main directory is just '/' and the server gets a request, whenever a client goes to the url and then it responds, in this case with a text document, 'Home page'.

Related

How can I redirect the user to a custom URL scheme with Express.js and node-fetch?

Sorry if my usage of server-related words is wrong, I'm new to this. I have two Express.js servers one on port 3000 and one on port 8000. The browser renders two different HTML files on these two ports. First I start the server on port 8000. As soon as I start the server on port 3000, I want to redirect the user viewing the site on port 8000 to a custom URL scheme to open an installed app (using "example://"). At the moment I console.log "received" on port 8000 as soon as the other server starts. How can I redirect the user to the URL "example://" so that the app opens?
This is my code for server one (port 3000):
import express, { response } from "express";
import fetch from "node-fetch";
import * as path from 'path';
import { fileURLToPath } from "url";
const touchpointApp = express();
const port = 3000;
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
touchpointApp.get('/', (req, res) => {
res.sendFile('/index.html', { root: __dirname });
});
touchpointApp.listen(port, () => {
console.log('Running on Port 3000');
fetch("http://192.168.2.127:8000/launch").then(res => {console.log("Success")});
})
And this is my code for server two (port 8000):
const { response } = require('express');
const express = require('express');
const open = require('open');
const router = express.Router();
const path = require('path');
const smartMirror = express();
router.get('/', function(req, res){
res.sendFile(path.join(__dirname + '/index.html'));
});
smartMirror.use('/', router);
smartMirror.listen(process.env.port || 8000);
console.log('Running on Port 8000');
smartMirror.get("/launch", (req, res) => {
console.log("Received");
res.status(200);
})
The code is currently Frankenstein's monster because of the previous tests. I'm using NodeJS to start the servers.
This is my understanding of your intent:
User in browser visits http://somehost:8000/someUrl and gets a page
You start server on port 3000, the 8000 server somehow detects this
Subsequent requests to http://somehost:8000/someUrl are now redirected to http://somehost:3000/differentUrl and hence the user is now navigating among pages in the 3000 server. Note that the 8000 server is telling the browser: "don't look here, go to the 3000 server for your answer".
If that is your intent then you can send a redirect by
smartMirror.get("/launch", (req, res) => {
res.redirect("http://somehost:3000/differentUrl");
})
So you might have code such as
smartMirror.get("/launch", (req, res) => {
// assuming that you can figure out that the 3000 server is running
if ( the3000ServerIsRunning ) {
let originalURL = req.originalUrl;
let redirectedURL = // code here to figure out the new URL
res.redirect("http://somehost:3000" + redirectedURL);
else {
// send a local respons
}
})
I think you can do it with the location http response header.
res.location('example://...')

React/NodeJS won't speak via localhost in development

I'm working to setup a Node backend to feed data and communicate with ReactJS for my frontend. Ultimately I am developing new company software to replace our current Transportation System.
I utilize Amazon EC2 Ubuntu 16.04 - for my own reasons for my business - and I simply cannot get my ReactJS frontend with Socket.IO to communicate with my nodeJS backend with Socket.IO on http://localhost:4000/.
This is my App.js in my react frontend when it calls
import React, { Component } from 'react';
import logo from './logo.svg';
import ioClient from 'socket.io-client';
import './App.css';
var socket;
class App extends Component {
constructor() {
super();
this.state = {
endpoint: 'http://localhost:4000/'
};
socket = ioClient(this.state.endpoint);
}
This is my nodeJS index for the backend
const mysql = require('mysql');
const http = require('http');
const express = require('express');
const cors = require('cors');
const app = express();
const server = http.createServer(app);
const io = require('socket.io').listen(server);
app.use(cors());
app.get('/', (req, res) => {
res.send('Server running on port 4000')
});
const sqlCon = mysql.createConnection({
host: 'localhost',
user: 'admin-user',
password: 'admin-pass',
database: 'sample'
});
sqlCon.connect( (err) => {
if (err) throw err;
console.log('Connected!');
});
io.on('connection', (socket) => {
console.log('user connected');
});
server.listen(4000, "localhost", () => {
console.log('Node Server Running on 4000')
});
I can get it to communicate via my actual Public IP address, but not via localhost. I really don't want to expose my backend on my public IP address to communicate with it for all users. This has probably been asked before, but I honestly can't find a clear answer for it anywhere and I've been looking for 3 days now. Node has no problem executing, and like I said if I create the socket.io connection from the public IP, I can get it to communicate and as far as I can tell node has no problem running the rest of the script as it connects to mariaDB no problem.
This is the error I keep receiving in my Chrome console.
polling-xhr.js:271 GET http://localhost:4000/socket.io/?EIO=3&transport=polling&t=MvBS0bE net::ERR_CONNECTION_REFUSED
polling-xhr.js:271 GET http://localhost:4000/socket.io/?EIO=3&transport=polling&t=MvBS3H8 net::ERR_CONNECTION_REFUSED
I'm running React via npm start for the time being, so my localhost:3000 is being reverse proxied to nginx for my React frontend to be visible on my public EC2 IP via port 80.
Any help is appreciated!
It may be a cross origin request issue. Have you tried to enable CORS on your app. You can also use proxy in your react app package.json if you do not want to enable cors on your app.
In your react app package.json you can add
"proxy":"http://localhost:4000"
It's probably because the port you are using isn't available in the server-side when it's running.
Use the server-side port like this,
var port = process.env.PORT || 3000;
server.listen(port, "localhost", () => {
console.log('Node Server Running on 4000')
});
and on the client-side just connect to the app URL, like,
this.state = {
endpoint: '/'
};
socket = ioClient(this.state.endpoint);
Just clean up your server a bit. Take this guy run him from whatever terminal or ide you use to get your server going.
let startTime = Date.now();
const express = require('express');
const bodyParser = require('body-parser');
const compression = require('compression');
var cors = require('cors');
const app = express();
app.use(compression());
app.use(bodyParser.json({ limit: '32mb' }));
app.use(bodyParser.urlencoded({ limit: '32mb', extended: false }));
const http = require('http').Server(app);
const io = require('socket.io')(http);
app.use(cors({ origin: 'null' }));
const request = require('request');
const port = 4000;
let pm2InstanceNumber = parseInt(process.env.NODE_APP_INSTANCE) || 0;
http.listen(port + pm2InstanceNumber, err => {
if (err) {
console.error(err);
}
console.log('Listening http://localhost:%d in %s mode', port + pm2InstanceNumber);
console.log('Time to server start: ' + (Date.now() - startTime) / 1000.0 + ' seconds');
setTimeout(() => {
try {
process.send('ready');
} catch (e) {}
}, 2000);
app.get('/', (req, res) => {
res.send('Server running on port 4000')
});
});
or just run node filename.js to serve this guy up.

How to use Socket.io combined with Express.JS (using Express application generator)

I'm trying to use Socket.io combined with Express.JS (using Express application generator).
I've found some aswers how to do this (Using socket.io in Express 4 and express-generator's /bin/www).My problem is that i cannot make use of the sockets inside the routes folder.
I can use them in the app.js and bin/www.js files. When i call the route index.js it just keeps loading the webpage for a long time without giving any errors.
bin/www.js
...
/**
* Create HTTP server.
*/
var server = http.createServer(app);
var io = app.io
io.attach( server );
...
app.js
...
// Express
var app = express();
// Socket.io
var io = socket_io();
app.io = io;
var routes = require('./routes/index')(io);
...
routes/index.js
module.exports = function(io) {
var app = require('express');
var router = app.Router();
io.on('connection', function(socket) {
console.log('User connected');
});
return router;
}
Here is a simple example on how to use Socket.io with Express that I made available on GitHub here:
https://github.com/rsp/node-websocket-vs-socket.io
The backend code is this:
var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
console.error('express connection');
res.sendFile(path.join(__dirname, 'si.html'));
});
io.on('connection', s => {
console.error('socket.io connection');
for (var t = 0; t < 3; t++)
setTimeout(() => s.emit('message', 'message from server'), 1000*t);
});
http.listen(3002, () => console.error('listening on http://localhost:3002/'));
console.error('socket.io example');
See https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js
As you can see here, I am creating the express app with:
var app = require('express')();
Then I create an http server with that app with:
var http = require('http').Server(app);
And finally I use that http server to create the Socket.io instance:
var io = require('socket.io')(http);
After running:
http.listen(3002, () => console.error('listening on http://localhost:3002/'));
it all works together.
You can see the entire example on GitHub with both backend and frontend code that works. It currently uses Express 4.14.0 and socket.io 1.4.8.
For anyone who still want to use socket.io and express http request. Easiest way is to create two seprate instance of http server listing to different ports. 1 for websockets and 2nd for api requests.
const express = require("express");
const app = express();
const httpServer = require("http").createServer(app);
const io = require("socket.io")(httpServer, {
path: '/'
});
// routes and io on connection
httpServer.listen(5000, () => {
console.log("Websocket started at port ", 5000)
});
app.listen(3000, () =>{
console.log("Http server listening at", 3000)
})

Node.js and Socket.io moving from local development server to live server, not connecting

I have built a private chat system using Node.js and Socket.io on my local development server, and it is working fine, sends messages, updates the database whenever the client accepts the message event. However, the past two days I have been trying to push this to my live Rackspace server. I have been chatting with Rackspace and they have spun up my node server, I have a console.log that prints "Server listening on port: xxxx". I will post my node.js server code as well as some of my client code. I am just not sure what is going wrong as it worked fine on my local development. Chrome console is giving me a error of 'io is not defined' which it is, which is making me think that it is not loading the socket.io/socket.io.js from the node server. However, I thought that it would give me an error on the GET request.
I am new to Node.js and Socket.io and do not understand everything about it. I am trying to use this on vhost host, could this cause a problem?
var express = require('express');
app = require('http').createServer(handler),
//server = require('http').createServer(app),
io = require('socket.io')(app);
fs = require('fs');
app.listen(3000, function() {
console.log("Server listening on: 3000");
});
var clients = {};
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
//app.get('/', function(req, res){
// res.sendFile(__dirname + '/index.html');
//});
io.sockets.on('connection', function(socket){
console.log("Connected!");
socket.emit('news', { hello: 'world' });
socket.on('add-user', function(data){
clients[data.username] = {"socket" : socket.id};
console.log(data.username+' / '+clients[data.username].socket);
});
socket.on('private-message', function(data){
console.log("Sending: " + data.content + " to " + data.username);
if (clients[data.username]){
io.sockets.connected[clients[data.username].socket].emit("add- message", data);
} else {
console.log("User does not exist: " + data.username);
}
});
//Removing the socket on disconnect
socket.on('disconnect', function() {
for(var name in clients) {
if(clients[name].socket === socket.id) {
delete clients[name];
break;
}
}
});
});
Client Code:
var socket = io;
socket.connect('x.x.x.x:3000');
var viewingUser = $('#viewingUserID').val();
socket.on("news", function (data) {
console.log(data);
});
socket.emit("add-user", {"username" : viewingUser });
So I replaced "<script type="text/javascript" src="xx.xxx.xxx.xxx:3000/socket.io/socket.io.js">" with "<script type="text/javascript" src="https://cdn.socket.io/socket.io-1.3.5.js"></script>"
This is the error:
GET http://23.253.247.166:3000/socket.io/?EIO=3&transport=polling&t=1439565622045-29 net::ERR_CONNECTION_REFUSED
Your server does not have a request handler for the socket.io javascript file.
You browse to your website and your server gets a request, you handle it by sending the index.html file.
When the index.html file is being processed by the browser, it will find the socket.io script tag and make a request to the server for it, but you only respond to requests by sending the index.html file.
Either:
Try replacing the script tag src with a CDN version of socket.io (client version).
or
Add a request handler to send the javascript file when requested
If you have to serve static content (like webpages / javascript / css / images / ...) express makes it very easy:
app.use(express.static('public')); Where public would be the folder of your static assets.
Server code:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendfile('index.html');
});
// Socket stuff goes here. but try this for a start
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('Server listening on:3000');
});

"Poorly formatted HTTP response" in node express app deployed to heroku

The following code works when deployed locally, receiving a request, and forwarding it to another server to validate a license:
var express = require("express");
var app = express();
var request = require("request");
var ddKey = "someKey";
var ddSecret = "someSecret";
var ProId = "someId";
var testLicense = "someLicense";
app.get("/", function(req, res){
var license = req.query["license"] || "test";
var url = "https://"+ddKey+":"+ddSecret+"#licenseServer.com/products/"+ProId+"/licenses/check_valid?key="+license;
request.get(url, {"auth": {"user": ddKey, "pass": ddSecret}, "json": true}, function(error, response, body){
res.send("BODY:", response.body);
});
});
var port = process.env.PORT || 3001;
app.listen(port, function(){
console.log("listening on port ", port);
});
When I deploy it on heroku however, and send a request to the heroku app I get a "no data received" screen along with this message:
Error 324 (net::ERR_EMPTY_RESPONSE): The server closed the connection without sending any data.
When I check the heroku logs I see that heroku is indicating the following error:
Poorly formatted HTTP response
I am unable to locate what constitutes a correctly formatted response.
Thank you for any help you can provide.

Categories

Resources