Socket.io not working in node.js express - node.js

I made an app with express generator, I'm using socket.io in my app but it's not working for me. I use socket.io in bin/www file and after the server created and listened to the port. after load the page that want to connect to the socket, browser's console show this error:
'socket.emmit is not a function'
here's the codes:
var app = require('../app');
var debug = require('debug')('server3:server');
var http = require('http');
var port = normalizePort(process.env.PORT || '8585');
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
};
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
};
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
};
var io = require('socket.io').listen(server);
io.on('connection', function(socket){
console.log('socket is on...');
});
It's the summary of my socket codes. the main codes are here. anyway it's not working!

The proper name of the method is socket.emit (single "m").

Related

Sockets.io issue: WebSocket is closed before the connection is established

I am currently building a nodejs webrtc video conference, hosted on azure. The program works perfectly fine locally, but when hosted there seems to be an issue with websockets. The client side error is below:
WebSocket connection to '<URL>' failed: WebSocket is closed before the connection is established.
index.js:83 WebSocket connection to 'wss://etuition.azurewebsites.net:8080/socket.io/?EIO=3&transport=websocket' failed: WebSocket is closed before the connection is established.
I have seen other stack overflow posts claiming that this is due to SSL, but site is currently running on HTTPS so this should not be a problem for me. Is it possible that the ws server is insecure even though my http server is secure?
Any other advice on what could be the problem will be greatly appreciated.
Below I have included my server.js code.
Please ask if any more information is needed:
/**
* Server module.
*
*
*/
'use strict';
var environment = process.env.RTC_ENV || 'local';
var debug = require('debug')('expressapp:server');
var express = require('express');
var cors = require('cors');
const http = require('http');
var logger = require('./logger').logger(environment);
var serverPort = normalizePort(process.env.PORT || '8080');
//var serverPort = normalizePort(process.env.PORT || '8080');
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
//var serverPort = process.env.RTC_PORT || 31000
var serverIpAddress = process.env.RTC_IP || 'localhost'
var socketIoServer = 'etuition.azurewebsites.net' + ':' + serverPort;
////////////////////////////////////////////////
// SETUP SERVER
////////////////////////////////////////////////
var app = express();
app.set('port', serverPort);
function redirectSec(req, res, next) {
if (req.headers['x-forwarded-proto'] == 'http') {
var redirect = 'https://' + req.headers.host + req.path;
console.log('Redirect to:' + redirect);
res.redirect(redirect);
} else {
return next();
}
}
app.use(redirectSec);
require('./router')(app, socketIoServer, environment);
// Static content (css, js, .png, etc) is placed in /public
app.use(express.static(__dirname + '/public'));
app.use(cors());
// Location of our views
app.set('views', __dirname + '/views');
// Use ejs as our rendering engine
app.set('view engine', 'ejs');
// Tell Server that we are actually rendering HTML files through EJS.
app.engine('html', require('ejs').renderFile);
const server = http.createServer(app);
server.listen(serverPort);
server.on('listening', onListening);
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
logger.info("Socket IO Address:" + socketIoServer);
logger.info("Server IP Address:" + serverIpAddress);
logger.info('Server running on port ' + serverPort);
}
var io = require('socket.io').listen(server, { log: false, origins: '*:*' });
////////////////////////////////////////////////
// EVENT HANDLERS
////////////////////////////////////////////////
io.sockets.on('connection', function (socket) {
function log() {
var array = [">>> Message from server: "];
for (var i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
socket.on('message', function (message) {
log('Got message: ', message);
logger.info("message: ", message);
socket.broadcast.to(socket.room).emit('message', message);
});
socket.on('create or join', function (message) {
var room = message.room;
socket.room = room;
var participantID = message.from;
configNameSpaceChannel(participantID);
io.of('/').in(room).clients(function (error, clients) {
var numClients = clients.length;
log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room', room);
if (numClients == 0) {
logger.info(participantID + " joined first. Creates room " + room);
socket.join(room);
socket.emit('created', room);
} else {
logger.info(participantID + " joins room " + room);
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
}
})
});
// Setup a communication channel (namespace) to communicate with a given participant (participantID)
function configNameSpaceChannel(room) {
var nsp = '/' + room;
var socketNamespace = io.of(nsp);
logger.info('ConfigNameSpaceChannel:' + nsp);
socketNamespace.on('connection', function (socket) {
socket.on('message', function (message) {
// Send message to everyone BUT sender
socket.broadcast.emit('message', message);
});
});
return socketNamespace;
}
});

ExpressJS not call ajax get method

I created a sample ExpressJS App by using Express Application Generator
I want to call localhost:3000/data to get some data. I added these code to app.js:
app.get('/data', function(req, res){
debug("get data");
});
Also I make ajax request in client side js file :
$.ajax({
url: 'http://localhost:3000/data/',
//url: 'http://localhost:3000/data', -> also not work
type:'GET',
dataType: 'json',
success: (data) => {
console.log("get data from client js", data);
}
});
but my app.get method never call. GET /data/ 404 written in console screen. Also when I typed http://localhost:3000/data on browser I got Not Found error. how can I fix this ?
my www file :
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('myapp:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
I'm not exactly sure where your problem lies because there isn't enough code displayed to determine that. instead I have written a simple express server for you to use:
const express = require('express');
const bodyParser = require('body-parser');
const CORS = require('cors');
const app = express();
app.use(bodyParser.json());
app.use(CORS());
app.get('/data', (req, res) => {
res.json({message: "working"});
});
app.listen(5000, () => {
console.log('Server listening on port 5000');
});

How can I implement clustering with sequelize ORM i.e. multithreading

Below is a piece of code I wrote but isn't working. With this code - how can I refactor it to implement multithreading or clustering so that I can utilize the number of cpus and thus improve the performance of my application?
if (cluster.isMaster) {
console.log('Master ${process.pid} is running');
for (let i = 0; i < numOfCpus; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log('worker ${worker.process.pid} died');
});
} else {
db.sequelize.sync({
force: false
}).then(function () {
app.listen(PORT, function (req, res) {
res.writeHead(200);
res.end('hey');
console.log("==> 🌎 Listening on port %s. Visit http://localhost:%s/ in your browser.", PORT, PORT);
});
console.log(' Worker ${process.pid} started');
});
}
I've been working on something similar. I saw in your comment that you moved on to create a Spring Boot application anyways, but just in case, I think your issue came from the callback you passed to the 'listen' method. You wrote the status 200 to the response header then ended the connection with res.end('hey');
Perhaps if you just call the 'listen' method and handle any other logic afterwards with the server.on('listening') method, it will solve your issue? It seems to work when I test it on my application. This is my bin/www so far, where app is an express application, and db is the Sequelize models:
#!/usr/bin/env node
/**
* Module dependencies.
*/
const http = require('http');
const cluster = require('cluster');
const os = require('os');
const config = require('../server/config')[process.env.NODE_ENV || 'development'];
const app = require('../server/app')(config);
const db = require('../server/models');
const log = config.log();
const numCPUs = os.cpus().length;
// Helper functions
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
const port = parseInt(val, 10);
if (Number.isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Get port from environment and store in Express.
*/
const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server and listen on the provided port
*/
const server = http.createServer(app);
if (cluster.isMaster) {
log.info(`Master ${process.pid} is running`);
for (let i = 0; i < numCPUs; i += 1) {
cluster.fork();
}
cluster.on('exit', (worker) => {
log.fatal(`Worker ${worker.process.pid} just died`);
cluster.fork();
});
} else {
db.sequelize.sync({ force: false })
.then(() => {
log.info('Connected to database');
server.listen(port);
})
.catch((err) => {
log.fatal(err);
});
}
server.on('listening', () => {
const addr = server.address();
const bind = typeof addr === 'string'
? `pipe ${addr}`
: `port ${addr.port}`;
log.info(`Listening on ${bind}`);
});
// Handle server errors
server.on('error', (error) => {
if (error.syscall !== 'listen') {
throw error;
}
const bind = typeof port === 'string'
? `Pipe ${port}`
: `Port ${port}`;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
log.fatal(`${bind} requires elevated privileges`);
process.exit(1);
break;
case 'EADDRINUSE':
log.fatal(`${bind} is already in use`);
process.exit(1);
break;
default:
log.info(error);
// throw error;
}
});

A standard for error handling and graceful shutdown of Node/Express server

Below is a basic script I usually use for my express servers. Specifically, I am looking for answers to the following questions: Is it needed to include SIGINT and SIGTERM process signal handlers in production? Do I need to actually include an uncaught exception handler? What about tracking and cleaning up sockets? Do I use process.exit(), process.exit(0), or process.exit(1), and if so, where exactly and why?
var express = require('express');
var sockets = [];
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
var port = 7000;
var app = express();
var server = app.listen(port, function () {
console.log(`app listening on port ${port}`);
})
.on("connection", onConnection)
.on("listening", onListening)
.on("error", onError)
.on("close", onClose);
var cleanup = function () {
server.close(function () {
console.log("Closed out remaining connections.");
process.exit();
});
sockets.forEach(function (socket) {
socket.destroy();
});
setTimeout(function () {
console.log("Could not close connections in time, forcing shut down");
process.exit(1);
}, 30 * 1000);
}
function onConnection(socket) {
sockets.push(socket);
}
function onError(error) {
if (error.syscall !== 'listen') throw error;
var bind = typeof port === 'string'? 'Pipe ' + port : 'Port ' + port;
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'? 'pipe ' + addr : 'port ' + addr.port;
console.log('Listening on ' + bind);
}

Express and Cluster node modules in the same app

I am creating an app that allows users to upload files in their browsers to a server.
I started it by typing express in the folder of my project. With that express created all the folders and such. It created a bin folder containing a www file that starts a lot of stuff for us like the ports.
At first i only had one core so i was doing it like so:
var express = require('express');
var multer = require('multer');
var app = express();
var done = false;
var fileSize = 0;
app.use(multer({ dest: './uploads/',
rename: function (fieldname, filename){
return filename;
},
onFileUploadStart: function(file){
console.log(file.originalname + ' is starting...');
},
onFileUploadComplete: function(file){
console.log(file.fieldname + ' uploaded to ' + file.path);
done = true;
},
onFileUploadData: function(file, data){
fileSize += data.length;
console.log("FileUpload " + fileSize);
}
}));
app.get('/', function(request, response){
response.sendFile(__dirname + '/index.html');
});
app.post('/upload/', function(request, response){
console.log(request.body);
if (done == true)
response.end('file uploaded');
});
module.exports = app;
Eventually i needed to user a machine with several cores in order to be able to respond to more client requests. So I am trying to use the cluster module.
I changed the code accordingly:
var cluster = require('cluster');
if(cluster.isMaster){
var numCPUS = require('os').cpus().length;
for(var i=0; i<numCPUS; i++)
cluster.fork();
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
cluster.on('online', function(worker) {
console.log('worker ' + worker.process.pid + ' started');
});
}else{
var express = require('express');
var multer = require('multer');
var app = express();
var done = false;
var fileSize = 0;
app.use(multer({ dest: './uploads/',
rename: function (fieldname, filename){
return filename;
},
onFileUploadStart: function(file){
console.log(file.originalname + ' is starting...');
},
onFileUploadComplete: function(file){
console.log(file.fieldname + ' uploaded to ' + file.path);
done = true;
},
onFileUploadData: function(file, data){
fileSize += data.length;
console.log("FileUpload " + fileSize);
}
}));
app.get('/', function(request, response){
response.sendFile(__dirname + '/index.html');
});
app.post('/upload/', function(request, response){
console.log(request.body);
if (done == true)
response.end('file uploaded');
});
module.exports = app;
}
The problem is that when i do this i am getting the following error in the console:
Run: node ./bin/www
Result:
app.set('port', port);
TypeERror: Cannot call method 'set' of undefined at Object.<anonymous>
This happens since i placed the entire code inside the forked childs of the master. Anyone knows why this happens and how i can fix it?
EDIT:
In here you can see the bin/www file where the port and some other configurations are set:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('dropbox:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

Resources