Socket.IO application not starting, no output - javascript

I have the following simple socket.io app :
var fs = require('fs');
var db = require("./libs/db.js");
var sslOptions = {
key: fs.readFileSync('/var/ssl/server.key'),
cert: fs.readFileSync('/var/ssl/server.crt'),
ca: fs.readFileSync('/var/ssl/ca.crt'),
requestCert: true,
rejectUnauthorized: false
};
var io = require('socket.io').listen(4000,sslOptions);
It runs, displaying : info: socket.io started on launch. The page example.com:4000 outputs : Welcome to socket.io, all good.
Now, in another directory, I have :
var fs = require('fs');
var sslOptions = {
key: fs.readFileSync('/var/ssl/server.key'),
cert: fs.readFileSync('/var/ssl/server.crt'),
ca: fs.readFileSync('/var/ssl/ca.crt'),
requestCert: true,
rejectUnauthorized: false
};
var io = require('socket.io').listen(2000,sslOptions);
That code (exactly the same??) doesn't output anything on launch...
socket.io versions are identical (1.1.0), both directories are chmoded the same.
What could cause such behaviour? How can I debug?
Edit :
When I cp the not working app in the same dir than the working app, it runs... Again, permissions are the same.

I copied the node_modules/socket.io of the working dir into the non-working one. It now works.
Still haven't got a clue what's happening. Both versions were installed using npm install, and npm socket.io version gave me the same "1.1.0".
I'll leave the question here, as it may help someone. Weird...

Related

How to PeerJS over the Internet?

in the local LAN everything is working very well, but over the internet it doesn't work.
i read a lot about WebRTC Signaling.
i use the following node.js peerjs server
whats wrong with my config?
var fs = require('fs');
var PeerServer = require('peer').PeerServer;
var server = PeerServer({
port: 3001,
debug: true,
path: '/peerjs',
ssl: {
key: fs.readFileSync('privkey.pem', 'utf8'),
cert: fs.readFileSync('fullchain.pem', 'utf8')
},
config: {'iceServers': [
{ url: 'stun:stun.l.google.com:19302' },
]}
});
First of all, you need to use a PeerServer that is not on your local network (=accessible to the internet). There is one provided by peer.js, which is used by default when no PeerServer URL is specified by the client.
To establish a connection, a library like socket.io can be very useful. This video gives a good explanation: https://www.youtube.com/watch?v=DvlyzDZDEq4

Does log4js require any extra code to work on an Apache server?

I'm trying to add Log4js-Node to a Node.js server running on Apache. Here's my code:
const path = require("path");
const express = require("express");
const log4js = require('log4js');
const app = express();
const logger = log4js.getLogger();
logger.level = "debug";
const port = 443;
log4js.configure({
appenders: { everything: { type: 'file', filename: 'logs.log', flags: 'w' } },
categories: { default: { appenders: ['everything'], level: 'ALL' } }
});
const server = app.listen(port, () => {
logger.debug("listening to requests on port " + port);
});
app.get("/log", (req, res) => {
res.sendFile(path.join(__dirname + "/logs.log"));
});
When I run the script on Node.js on my computer and navigate to localhost:443/log I see what I expect, which is this:
[2020-03-17T22:50:43.145] [DEBUG] default - listening to requests on port 443
But when I run the code on a remote server it crashes and I get this in the error page (with part of the path replaced by me with "[removed]"):
App 25925 output: at Server. ([removed]/index.js:27:9)
App 25925 output: at Logger. [as debug] ([removed]/12/lib/node_modules/log4js/lib/logger.js:124:10)
App 25925 output: at Logger.log ([removed]/12/lib/node_modules/log4js/lib/logger.js:73:12)
App 25925 output: at Logger._log ([removed]/12/lib/node_modules/log4js/lib/logger.js:90:16)
App 25925 output: at Object.send ([removed]/12/lib/node_modules/log4js/lib/clustering.js:97:15)
App 25925 output: [removed]/12/lib/node_modules/log4js/lib/clustering.js:97
App 25925 output: at Object. ([removed]/12/lib/node_modules/log4js/lib/clustering.js:8:13)
I'm using A2 Hosting which uses Apache 2.4.41. I opted for Node.js 12.9.0, and Log4js 6.1.2. The package.json should be the same on both my computer and the server, and I've run npm install on both.
Is this just an issue with Log4js and the server, or have I missed something somewhere?
This was actually a relatively simple fix. The path referenced by the last error in the stack trace is a Log4js module that implements clustering support through Node's "cluster" module. The line "8" referenced is cluster = require("cluster"). It's wrapped in a try/catch block like this:
try {
cluster = require("cluster"); //eslint-disable-line
} catch (e) {
debug("cluster module not present");
disabled = true;
}
The installation of Node.js on my computer came with the "cluster" module, however as far as I can tell, the server I'm using doesn't support it. Also, the version of Node I'm using on my computer is newer than what I'm using on the server (so I've now installed 12.9 on my machine). I believe the older version of Node doesn't bother trying to catch the exception and tries to load the cluster module, fails, and then throws the error.
So the simple fix was to comment out most of the "try/catch" block, leaving just the contents of "catch" like this:
// try {
// cluster = require("cluster"); //eslint-disable-line
// } catch (e) {
debug("cluster module not present");
disabled = true;
// }
If someone has a better fix, I'm open to suggestions.
The same response of #skittleswrapper,thx, it work for me.
I use Node.js 14.18.1 with log4js 6.3.0.
But i wondering what'is the necessary of this module 'cluster' and if we can
add it to our app in other way.

How do I fix socketio spamming polling when I start my web app? [javascript, expressjs, socketio]

Here is the problem. When I load the page in the browser and check to see if my "test" was emitted, I run into this wall of spamming polling.
The code I use is exactly the same as in other projects I have done, so it makes no sense to me that this doesn't work now. -_-
app.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = process.env.PORT || 8000;
server.listen(port, function(){
console.log('server ready - listening on *:8000');
});
app.get( '/*' , function( req, res, next ) {
//This is the current file they have requested
var file = req.params[0];
//Send the requesting client the file.
res.sendFile( __dirname + '/' + file );
});
io.on('connection', function (socket) {
socket.on('test', function(){
console.log("test worked");
});
});
client.js
var socket = io();
socket.emit("test");
I broke the code down to what you see above. There's nothing else. And it doesn't work. internal screaming
I'll post my comment as an answer so you can wrap up this question. One common reason that socket.io will loop with http requests and never successfully connect is if you are running mismatched version on the client and server. This seems to have happened recently with socket.io upon a recent version change so they must have made some change in how the connection logic works that makes it fail to connect if versions are mismatched.
If you load your client via this:
<script src="/socket.io/socket.io.js"></script>
Then, the client will always match the server version as long as you don't have any other <script> tags that are loading some other version of socket.io.
One more solution which worked for me ( Socket.IO 2.3.0 and Socket.IO Client 2.3.0 ) is to set the transports field when you create the instance of io on back-end and socket on front-end , like this :
On back-end :
io = require('socket.io')(http,{
log: false,
agent: false,
origins : '*:*' , // this is for the CORS browser error , I also use the cors npm module here
transports : [ 'websocket' ]
});
And on front-end :
const socket = socketIOClient(url,{
forceNew : false ,
secure : true ,
transports: [ 'websocket' ]
});
Hope it helps , if not the question owner , then maybe the others :)

Creating Node.JS HTTPS server in Cloud9 IDE

Is it somehow possible to create a Node.js https server in cloud9 IDE?
Below is my example of simple https server setup in Node.js.
var https = require('https');
var fs = require('fs');
var app = require('./app');
// SSL Configuration
var ca_names = ['CERT-NAME_1', 'CERT-NAME_2', 'CERT-NAME_3'];
var options = {
key: fs.readFileSync('./folder/server.key'),
cert: fs.readFileSync('./folder/server.crt'),
ca: ca_names.map(function(n) {
return fs.readFileSync('./eid/ca/' + n + '.crt');
}),
//crl: ca_names.map(function(n) { return fs.readFileSync('/eid/ca/' + n + '.crl'); }),
requestCert: false,
rejectUnauthorized: false
};
var server = https.createServer(options, app);
server.listen(process.env.PORT || 8081, process.env.IP || "0.0.0.0");
console.log('server listening on port: ' + process.env.PORT);
when I try to connect to the server then I am getting following error:
"ECONNRESET: Request could not be proxied!"
I think the problem is you are trying to listen to both HTTP and HTTPS.
c9 works as a proxy so you only need to listen on HTTP even though you are trying to use HTTPS. Try not listening to HTTPS and it should work. (more info on this)
But, if you really need HTTPS, in that case you can use a proxy like Nginx to internally proxy requests over HTTPS.(more info on this)enter link description here

Best way to store DB config in Node.Js / Express app

What would be the best way to store DB config (username, password) in an open source app that runs on node.js / Express? Two specific questions:
Shall I put it into a separate config.js file in /lib folder, for example, and never include it into the master repository that is publicly available on GitHub?
To inlcude the config, is it as simple as require('./config.js') from the file that needs it or is there a better way of doing it?
PS sorry if the questions seem a bit simple or not so well formulated, but I'm just starting :)
Here's how I do it:
Create a config.js which contains objects representing your configs:
var config = {
development: {
//url to be used in link generation
url: 'http://my.site.com',
//mongodb connection settings
database: {
host: '127.0.0.1',
port: '27017',
db: 'site_dev'
},
//server details
server: {
host: '127.0.0.1',
port: '3422'
}
},
production: {
//url to be used in link generation
url: 'http://my.site.com',
//mongodb connection settings
database: {
host: '127.0.0.1',
port: '27017',
db: 'site'
},
//server details
server: {
host: '127.0.0.1',
port: '3421'
}
}
};
module.exports = config;
Then in my index.js (or wherever really),
var env = process.env.NODE_ENV || 'development';
var config = require('./config')[env];
Then process with that object, e.g.
var server = express();
server.listen(config.server.port);
...
For running toy apps where I need to hide db credentials, I use the dotenv module.
Place your sensitive info in a .env file (which is .gitignored), place require('dotenv').config(); in your app; dotenv creates entries in process.env that you can refer to.
.env file:
DATABASE_PASSWORD=mypw
DATABASE_NAME=some_db
To refer to the values:
process.env.DATABASE_PASSWORD
Not sure whether this is the best practice, but personally I have a config.json file where I store my db connection information. Then I do the following:
// options.js
var fs = require('fs'),
configPath = './config.json';
var parsed = JSON.parse(fs.readFileSync(configPath, 'UTF-8'));
exports.storageConfig= parsed;
Then from a different file I do the following:
var options = require('./options');
var loginData = {
host: options.storageConfig.HOST,
user: options.storageConfig.user,
password: options.storageConfig.password
};
I do put in args. just like the port of so many node.js example.
you most likely forever, pm2, nodemon to run your app. so this variable is not check in as part of your source code. and they are globally available too.
process.env.PORT
process.env.DATABASE_USER
process.env.DATABASE_PASSWORD
PORT=3000 DATABASE_HOST=localhost DATABASE_USER=admin DATABASE_PASSWORD=mypassword node app.js
export PORT=3000
export DATABASE_HOST=localhost
export DATABASE_PORT=27017
export DATABASE_USER=admin
export DATABASE_PASSWORD=mypassword
node app.js
var server = app.listen(process.env.PORT, function() {
});
var mongoClient = new MongoClient(new Server(process.env.DATABASE_HOST, process.env.DATABASE_PORT));
To inlcude the config, is it as simple as require('./config.js') from the file that needs it or is there a better way of doing it?
This is the right way to store config files.
The best approach would be to write your entire application like an ordinary node.js module, and write a small start-up file that calls it. This idea also allow you to use different database drivers using dependency injection.
Good, but not perfect solution is the environment. It is shared among all application, so if you have certain data you want to be available to all of them, this is the best bet. But if you have a config for one particular app, not much so.
PS: And please, don't use JSON for this. It's the worst idea possible. :)
I found this a nice way to handle my config, considering different environments:
config.coffee
exports.setEnvironment = (env) ->
switch env
when "development"
exports.DEBUG_LOG = true
exports.DB_PORT = '27017'
# ...
when "testing"
exports.DEBUG_ERROR = true
exports.DEBUG_CLIENT = true
# ...
when "production"
exports.DEBUG_LOG = false
# ...
else console.log "environment #{env} not found"
server.coffee:
config = require('./config')
config.setEnvironment env
Using environment variables
You can use export to set environment variables in OSX and Linux. The following is an example of setting a value in the SESSION_SECRET key.
export SESSION_SECRET="keyboard cat"
In Windows, you can use set.
set SESSION_SECRET="keyboard cat"
You can also set environment variables each time you run them.
SESSION_SECRET="keyboard cat" node secret-env.js
Use process.env of node.js to access environmental variables within code.
var express = require('express')
var session = require('express-session')
var app = express()
app.use(session({secret: process.env.SESSION_SECRET}))
Request a argument from the command-line
The best way to protect confidential information is not to store it in a setup file.
If the command-line requests configuration information as an argument using the noopt package, the secret information does not need to exist as a file.
The following is an example of requesting a session key as an argument using the noopt package.
var nopt = require("nopt")
var longOpts = {
"sessionSecret": String,
}
var shortOpts = {
"s": ["--sessionSecret"],
}
var parsed = nopt(longOpts, shortOpts, process.argv, 2)
console.log("session secret is:", parsed.sessionSecret)
node secret-arg.js --sessionSecret "keyboard cat"
node secret-arg.js -s "keyboard cat"
Advantages : It is safer to expose confidential information than to hardcoding or having it as a configuration file.
Disadvantages : There is a hassle of increasing the amount of information to be entered each time the app is launched.
If you try to create and solve a script, the problem that the password still exists in the script remains.

Categories

Resources