Im using node js with express framework and socket.io in my project.
when i load test page in browser(with this address: http://localhost:3001/test) every thing is fine and print "a user connected" in server log but when i refresh page again print that message two time and with another refresh print that message three times and with every refresh repeat that message.
whats wrong in my code ?
thanks.
test.js
var express = require('express');
var router = express.Router();
var io = require('../app');
router.get('/', function(req, res, next) {
io.on('connection', function(socket){
console.log('a user connected');
});
res.render('test', { title: 'test' });
});
module.exports = router;
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var session = require('express-session')
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(3001);
module.exports = io;
var index = require('./routes/index');
var users = require('./routes/users');
var test = require('./routes/test');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
app.use('/test', test);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
You are adding an additional event handler on every GET / request.
You only need to add the event handler once, outside of a http route. Think of it as the socketio equivalent of a route.
var io = require('socket.io')(server);
io.on('connection', function(socket){
console.log('a user connected');
});
Then in your router, just deal with the http request
router.get('/', function(req, res, next) {
res.render('test', { title: 'test' });
});
Related
I am working on a Nodejs Web application project which is based on Express Framework. I am working on creating a Sign up page. After giving the username and password the url should be redirected to profile page. In the views folder I created a file "profile.hbs". But the profile is not being recognized and I getting 404 not found. Please share your ideas on how to debug this issue.Thanks in advance.
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var expressHbs=require('express-handlebars');
var mongoose=require('mongoose');
var session=require('express-session');
var passport=require('passport');
var flash=require('connect-flash');
const mocha=require('mocha');
var validator=require('express-validator');
var indexRouter = require('./routes/index');
//var usersRouter = require('./routes/users');
var app = express();
mongoose.connect('mongodb://localhost:27017/shopping');
require('./config/passport');
// view engine setup
app.engine('.hbs',expressHbs({defaultLayout:'layout',extname:'.hbs'}));
app.set('view engine', '.hbs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(validator());
app.use(cookieParser());
app.use(session({secret:'mysupersecret',resave:false,saveUninitialized:false}));
app.use(passport.initialize());
app.use(flash());
app.use(passport.session());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
//app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Routing file
var express = require('express');
var router = express.Router();
var csrf=require('csurf');
var passport=require('passport');
const canine= require('../models/dogfood');
var csrfProtection=csrf();
router.use(csrfProtection);
/* GET home page. */
router.get('/', function(req, res, next) {
canine.find(function(err,docs){
var productChunks=[];
var chunkSize=3;
for(var i=0;i<docs.length;i += chunkSize){
productChunks.push(docs.slice(i,i+chunkSize));
}
res.render('shop/index', { title: 'Express',diets:productChunks});
});
});
router.get('/user/signup',function(req,res,next){
res.render('user/signup',{csrfToken:req.csrfToken()})
});
router.post('user/signup',passport.authenticate('local.signup',{
successRedirect:'user/profile',
failureRedirect:'user/signup',
failureFlash:true
}));
router.get('user/profile',function(req,res,next) {
res.render('user/profile');
});
module.exports = router;
You have a typo in the route name. It should be '/user/profile'
router.get('/user/profile', function(req,res,next) ...
I am working on a Nodejs Web application project which is based on Express Framework. I am working on creating a Sign up page. After giving the username and password the url should be redirected to profile page. In the views folder I created a file "profile.hbs". But the profile is not being recognized and I getting 404 not found. Please share your ideas on how to debug this issue.Thanks in advance.
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var expressHbs=require('express-handlebars');
var mongoose=require('mongoose');
var session=require('express-session');
var passport=require('passport');
var flash=require('connect-flash');
const mocha=require('mocha');
var validator=require('express-validator');
var indexRouter = require('./routes/index');
//var usersRouter = require('./routes/users');
var app = express();
mongoose.connect('mongodb://localhost:27017/shopping');
require('./config/passport');
// view engine setup
app.engine('.hbs',expressHbs({defaultLayout:'layout',extname:'.hbs'}));
app.set('view engine', '.hbs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(validator());
app.use(cookieParser());
app.use(session({secret:'mysupersecret',resave:false,saveUninitialized:false}));
app.use(passport.initialize());
app.use(flash());
app.use(passport.session());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
//app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Routing file
var express = require('express');
var router = express.Router();
var csrf=require('csurf');
var passport=require('passport');
const canine= require('../models/dogfood');
var csrfProtection=csrf();
router.use(csrfProtection);
/* GET home page. */
router.get('/', function(req, res, next) {
canine.find(function(err,docs){
var productChunks=[];
var chunkSize=3;
for(var i=0;i<docs.length;i += chunkSize){
productChunks.push(docs.slice(i,i+chunkSize));
}
res.render('shop/index', { title: 'Express',diets:productChunks});
});
});
router.get('/user/signup',function(req,res,next){
res.render('user/signup',{csrfToken:req.csrfToken()})
});
router.post('user/signup',passport.authenticate('local.signup',{
successRedirect:'user/profile',
failureRedirect:'user/signup',
failureFlash:true
}));
router.get('user/profile',function(req,res,next) {
res.render('user/profile');
});
module.exports = router;
Apart from adding a view file you should also add a new route which renders that view
app.get('/', function (req, res) {
res.render('profile.hbs', {
title: 'Profile',
// and any extra data you need, probably coming from your auth middleware
});
});
I have searched all over but all I find are basic ways to use socket.io.
I am trying to use socket.io in one of my routes but cant. I am using express, node.js, and jade. My issues is that i cant access io variable form app.j in other routes. Im not sure if am just supposed to call it every time. Also, when i try to requre the exported app.js modules its says that the app.j could not be found.
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var app = express();
//SOCKET/I/o
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = process.env.PORT || 3000;
//
var login = require('./routes/login');
var index = require('./routes/index');
var users = require('./routes/users');
var news = require('./routes/news');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
// TODO Not sure if this is working
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', login);
app.use('/index',index);
app.use('/users', users);
app.use('/news',news);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
/routes/login.js
var express = require('express');
var app = require('./app');
var firebase = require("firebase");
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('login');
});
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
module.exports = router;
/views/login.jade
doctype html
html
head
title login
link(rel='stylesheet', href='/stylesheets/main.css')
body
input(type="email",placeholder="email",id="userEmail")
input(type="password",placeholder="password",id="userPassword")
script(src="https://cdn.socket.io/socket.io-1.2.0.js")
script.
socket.on('connection', function (data) {
console.log(data);
socket.emit('my other event', {my: 'data'});
});
button(onclick='signin()') Sign In
button(onclick='signup()') Sign Up
As you're not running a single-page-app with html-router, the Socket.io instance is only initialised on the first route, so for every route you have to do this:
var socket = io()
socket.on('connection', function (data) {
console.log(data);
socket.emit('my other event', {my: 'data'});
});
Only then it would work.
I am learning to use socket.io, but when I add
script(type='text/javascript', src='/socket.io/socket.io.js')
in my client, and I add code:
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function(socket){
console.log('------------connection');
});
in app.js, but my client do get 404 error when trying to get /socket.io/socket.io.js.
I chage my code to :
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
var server = require('http').createServer();
var io = require('socket.io').listen(server);
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
var userlist = {};
io.on('connection', function(data){
console.log('------------connection');
socket.name = data.user;
if (!userlist[data.user]) {
userlist[data.user] = data.user;
};
io.emit("online", { userlist: userlist, user: data.user});
});
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
module.exports = app;
and I also have the code as follow in my javascript:
$(document).ready(function() {
var socket = io.connect('http://localhost:3000');
// other code
}
My application works when i specify a port number to socket.io that is diffrent from the server port number. The working code goes as follows:
This is my app.js file:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var configDB = require('./config/database.js');
var session = require('express-session');
var passport = require('passport');
var routes = require('./routes/index');
var auth = require('./routes/auth.js');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.set(process.env.PORT || 1337);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({ secret: 'mysessionsecret' }));
app.use(passport.initialize());
app.use(passport.session());
mongoose.connect(configDB.url);
app.use('/', routes);
app.use('/auth', auth);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
var talk = require('./socket/talk.js')(app);
module.exports = app;
This is my talk.js file:
var init = function (app){
var server = require("http").createServer(app).listen(3000);
var io = require("socket.io").listen(server);
var socketioJwt = require("socketio-jwt");
var jwtSecret = require('../config/jwtSecret');
console.log("init");
io.set("authorization", socketioJwt.authorize({
secret: jwtSecret,
handshake: true
}));
io.sockets.on("connection", function (socket) {
console.log("connected");
socket.on("send", function (data) {
console.log(data);
var username = data.username;
var message = data.message;
var datetime = data.datetime;
socket.broadcast.emit("send", data);
});
socket.on("busy", function () {
socket.emit("busy");
socket.broadcast.emit("busy");
});
socket.on("free", function () {
socket.emit("free");
socket.broadcast.emit("free");
});
});
}
module.exports = init;
This is my script tag in index.ejs:
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
And finally this is my io connect from the client:
socket = io("http://localhost:3000/",{
query: 'token=' + tok
});
This works but the problem is that i want to publish my site to Azure but it is not possible to let a Azure website listen to diffrent ports. At least i think it is not possible.
One of the many things I tried is changing the talk.js file to this:
var init = function (app){
var server = require("http").createServer(app).listen(app.get('port'));
var io = require("socket.io").listen(server);
...
But i it doesn't work. I always get something along the lines of http://localhost/socket.io/socket.io.js not found
If i change the script tag in my index.ejs file to this
<script src="http://cdn.socket.io/socket.io-1.2.1.js"></script>
The socket.io.js file gets loaded but when i connect form te client side i get a continious 404 not found error.
I looked at a lot of solutions online but none of them work. I really don't know what i am doing wrong.
This error comes from the bin/www.js file being called before app.js when using npm start. A quick solution is to bypass www.js, which is only used to handle some common errors, as it is suggested in this answer.
This github repo is an implementation of this solution and can be used as a starting point for any Express.js + socket.io application.