I'm using node.js, express, socket.io, mongodb, mongoose, mongolab and heroku to build simple chat.
Everything work great on the localhost (without heroku), but when I deploy my app on the heroku the socket.io.js not loading.
https://prnt.sc/gm6fz0
I've read about 10-20 other similiar questions and tried other variations, but socket.io.js still won't load.
app.js - server side
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 = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var mongoose = require('mongoose');
var mongodb = require('mongodb');
server.listen(8080);
var uri = 'mongodb://username:password#ds141264.mlab.com:41264/chat';
var index = require('./routes/index');
var users = require('./routes/users');
mongoose.connect(uri, function(err){
if(err) {
console.log(err);
} else {
console.log('connected to mongo db');
}
});
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback () {
var chatSchema = mongoose.Schema ({
msg: String,
created: {type: String, default: function(){return new Date()}}
});
var Chat = mongoose.model('Message', chatSchema);
io.on('connection', function(socket){
console.log('a user connected');
var query = Chat.find({});
query.sort({'_id': -1}).limit(10).exec(function(err, docs){
if (err) throw err;
console.log('sending old msgs');
socket.emit('load old msgs', docs);
});
socket.on('disconnect', function(){
console.log('user disconnected');
});
socket.on('chat', function(msg){
console.log('message: ' + msg);
var newMsg = new Chat({ msg: msg });
newMsg.save(function(err){
if(err) throw err;
io.emit('chat', msg);
});
});
});
});
app.use(express.static(__dirname + '/public'));
// 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(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);
// 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;
global.js - client-side
var socket = io.connect();
$('#send-message-btn').click(function () {
var msg = $('#message-box').val();
socket.emit('chat', msg);
$('#message-box').val('');
return false;
});
socket.on('chat', function (msg) {
var dadd = new Date;
$('#messages').append($('<time>').text(dadd));
$('#messages').append($('<p>').text(msg));
});
socket.on('load old msgs', function(docs){
for(var i=0; i < docs.length; i++) {
$('#messages').prepend($('<p>').text(docs[i].msg));
$('#messages').prepend($('<time>').text(docs[i].created));
}
});
As Per the documentation provided on heroku (Apps using Socket.io should enable session affinity. If you plan to use node’s Cluster module or to scale your app to multiple dynos, you should also follow Socket.io’s multiple-nodes instructions.), You Basically have to execute the following command from you project directory.
heroku features:enable http-session-affinity
Best,
Daksh Miglani
Related
I am unable to retrieve data from mongodb.
Problem is: the code Article.find({}); is not working to retrieve data from database.
I am using WebStorm IDE. I want to retrieve all the data from data base.
Please help me to find the error in my code.
database.js
module.exports = {
database:'mongodb://localhost:27017/shopping_site',
}
models/article.js
let mongoose = require('mongoose');
// Article Schema
let articleSchema = mongoose.Schema({
title:{
type: String,
required: true
},
author:{
type: String,
required: true
},
body:{
type: String,
required: true
}
});
let Article = module.exports = mongoose.model('Article', articleSchema);
index.pug
extends layout
block content
h1 #{title}
ul.list-group
each article, i in articles
li.list-group-item= article.title
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 mongoose = require('mongoose');
var config = require('./config/database');
var bodyParser = require('body-parser');
var app = express();
// Bring in Models
let Article = require('./models/article');
//database connectionkjvhgc
mongoose.connect(config.database);
let db = mongoose.connection;
// Check connection
db.once('open', function(){
console.log('Connected to MongoDB');
});
// Check for DB errors
db.on('error', function(err){
console.log(err);
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// Home Route
app.get('/', function(req, res){
Article.find({}, function(err, articles){
if(err){
console.log(err);
} else {
res.render('index', {
title:'Articles',
articles: articles
});
}
});
});
//set routes
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
//body-parser
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
// 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;
move database connection code into db.js and import same in article.js
db.js
let uristring = <your connection string or import database.js>;
mongoose.connect(uristring);
// When successfully connected
mongoose.connection.on('connected', function() {
console.log('Mongoose connection open to cluster');
});
// If the connection throws an error
mongoose.connection.on('error', function(err) {
console.log('Mongoose connection error: ' + err);
});
// When the connection is disconnected
mongoose.connection.on('disconnected', function() {
console.log('Mongoose connection disconnected');
});
// When the connection is open
mongoose.connection.on('open', function() {
console.log('Mongoose connection is open');
});
module.exports = mongoose;
then in article.js
const mongoose = require('mongoose');
require('../db');
First lets bring in your model,
require('./models/article');
the create a variable for the model
const Article = mongoose.model('Article');
Next to display your articles from db
app.get('/', (req, res) => {
Article.find({}).then(Article => {
res.render('index', {Article:Article});
}).catch(err => console.log(err));
});
I hope this helps
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.
Unable to integrate socket io and express js .
Below is my html code.
<html>
<head>
</head>
<body>
hello world.
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
</script>
</body>
</html>
This is my app.js of express 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 routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(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(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.get('/', function(req, res){
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
io.on('connection', function(socket){
console.log('client connected.');
});
// 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: {}
});
});
module.exports = app;
Problem : Unable to connect socket io with express.
Below is the image which shows errors in developer console, when i run the app.
Using your same code, removing var routes = ... and var users = ...
and adding at the end server.listen(3000); instead of the exports it just works for me.
https://dripr.io/file/NkWBbbHR
This code works for me
const express = require('express')
const socketIo = require('socket.io')
const http = require('http')
const app = express()
const server = http.createServer(app)
const io = socketIo(server)
io.on('connection',(socket)=>{
console.log('client connected: ',socket.id)
socket.on('disconnect',(reason)=>{
console.log(reason)
})
})
server.listen(5000, err=> {
if(err) console.log(err)
console.log('Server running on Port ', PORT)
})
const http = require("http");
const port = 4000;
const { joinUser, removeUser, findUser } = require('./users');
const app = http.createServer((req, res) => {
res.writeHead(200, headers);
res.end("API");
return;
});
const server = app.listen(port, () => {
console.log('Server Started..');
});
const io = require("socket.io")(server, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}
});
io.on('connection', (socket) => {
console.log('socket connected..', socket.id);
socket.on('chat', (data) => {
io.sockets.emit('send data', {
id: socket.id
});
io.sockets.emit('chat', { data: data, id: socket.id });
});
socket.on('typing', (data) => {
socket.broadcast.emit('typing', data);
});
socket.on("disconnect", () => {
const user = removeUser(socket.id);
console.log(user);
if (user) {
console.log(user.username + ' has left');
}
console.log("disconnected");
});
});
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.
I am trying to make a simple chat application using Node.js, socket.io, and express. However, if I click the send button in the main.jade file, the page refreshes, and no message appears. I also get this error in Firebug:
The connection to ws://127.0.0.1:3000/socket.io/?EIO=2&transport=websocket&sid=d_hNMPdXHed-j7LrAAAH was interrupted while the page was loading.
Main.jade
doctype html
html
head
meta(charset = "UTF-8")
script(src="/socket.io/socket.io.js")
script(src="http://code.jquery.com/jquery-1.11.1.js")
script.
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
body
ul#messages
form(action = "")
input#m(type = "text")
button Send
app.js
var express = require('express')
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongo = require('mongodb');
var mongodb = require("mongodb");
var monk = require('monk');
var db = monk('localhost:27017/pesterchum');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(function(req,res,next){
req.db = db;
next();
});
app.use('/', routes);
app.use('/users', users);
/// 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: {}
});
});
module.exports = app;
www
#!/usr/bin/env node
var debug = require('debug')('app');
var app = require('../app');
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
var io = require('socket.io').listen(server);
io.sockets.on('connection', function(socket){
socket.on('chat message', function(msg){
io.sockets.emit('chat message', msg);
});
});
index.js
var express = require('express');
var router = express.Router();
/* GET Main page. */
router.get('/main', function(req, res) {
res.render('main', { title: 'Main'});
});
It seems that the page is being reloaded because you've forgotten to wrap your client js code with $(document).ready(function() { ... });