I'm trying to set up my node server to update all the connected clients with new information in real-time. When I run the code below, the io.sockets.on('connection') callback is fired constantly, flooding the console with the message Client connected!, and the front-end is not being updated from socket.emit(). What am I doing wrong?
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 mongoose = require('mongoose');
var models = require('./models.js');
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('/', routes);
app.use('/users', users);
/// catch 404 and forwarding 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;
// Connect to the Mongo database
mongoose.connect('mongodb://localhost/test');
bin/www.js
#!/usr/bin/nodejs
var debug = require('debug')('my-application');
var app = require('../app');
app.set('port', process.env.PORT || 3000);
var io = require('socket.io').listen(app.listen(app.get('port')));
io.sockets.on('connection', function(socket) {
console.log('Client connected!');
socket.on('message', function(data) {
console.log('Sending update!');
socket.emit('update', 'Working!');
});
});
public/javascripts/update.js
var socket = io.connect('http://' + document.location.hostname + ':3000/');
socket.on('connect', function() {
console.log('Socket connected!');
socket.emit('message', 'Message from client');
});
socket.on('update', function(data) {
alert(data);
});
And when I end the npm process, the client begins to log
http://<ip>:3000/socket.io/?EIO=2&transport=polling&t=1498772846992-691 net::ERR_CONNECTION_REFUSED
I've read posts about the express router messing with the socket requests but I can't seem to get it working no matter what I try.
Can you try this setup?
EDITED:
app.js:
var express = require('express');
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'pug');
app.get('/', function (req, res) {
res.render('index');
});
module.exports = app;
bin/www.js:
var app = require('../app');
var http = require('http');
var server = http.createServer(app);
server.listen(process.env.PORT || '3000', function () {
console.log('server listens on port 3000');
});
var io = require('socket.io')(http);
io.listen(server);
io.on('connection', function(socket) {
console.log('Client connected!');
socket.on('message', function (data) {
console.log('Sending update!');
socket.emit('update', 'Working!');
});
});
index.pug (or jade, they say jade is obsolete):
doctype html
html
body
h1 Testing socket.io
h3#status not connected
br
p#update update: 
script(src="/socket.io/socket.io.js")
script.
var socket = io();
socket.on('connect', function() {
document.getElementById("status").innerHTML = "connected";
socket.emit('message', 'Hello!');
});
socket.on('update', function (data) {
document.getElementById("update").innerHTML += data;
});
Calling app.listen (where app is the result of invoking express()) returns an HTTPServer, which can be used to setup the socket connection:
var server = app.listen(port);
var io = socket(server);
without manually running your solution, I'd guess that because you're creating a new HTTPServer to be feed into the socket, it's somehow getting hung in a loop.
Related
my database in mongoDb is connected to my nodeJS i can read it there my nodeJs api is connected to my client-side (in reactJS) and i can send data from my nodeJs api using express-generator to my client-side and is working but when i tried to send my mongoDb database to the client-side is not working( but i'm still getting status 200 but my array is not here . I can't figure out why? i cant see the db when i call the api in postman so i assume the error is in the server-side . If i had a consol.log i can see the db but when i use return it is not working and i cant see the data in postman
here my nodeJs code:
var mongodb = require('mongodb')
var MongoClient = mongodb.MongoClient
var connectionURL = 'mongodb://127.0.0.1:27017'
var databaseName = 'projet_Ecommerce';
const dataFromDb = () => {
MongoClient.connect(connectionURL, {
useNewUrlParser: true
}, (error, client) => {
if (error) {
return console.log('Unable to connect to database')
}
console.log('Connected correctly !');
var db = client.db(databaseName)
db.collection('product').find().toArray(function(error, data) {
if (error) {
return console.log('Unable to find the user')
}
return (data);
})
// Pointer - go to doc
// db.collection('tasks').find({completed: false}).toArray()
})
};
module.exports = dataFromDb
routres / index.js:
var express = require('express');
var router = express.Router();
const bodyParser = require('body-parser')
var dataC = require('../public/javascripts/dataFromDb')
// data = JSON.stringify(data);
// console.log(dataFromDb())
/* GET home page. */
router.get('/', function(req, res, next) {
//console.log(dataFromDb())
res.send(dataC())
});
//console.log(dataFromDb())
module.exports = router;
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 cors = require("cors")
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var testAPIRouter = require("./routes/testAPI");
var app = express();
var bodyParser = require("body-parser")
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
// app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use("/testAPI", testAPIRouter);
// 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;
other files no change
I am using socket.io to make a MEAN app. I am sending a event through my node, the event is defined in my index.js file which is included in my app.js. I am getting a 404 error while running my angular app.
let express = require('express');
let router = express.Router();
let server = require('http').Server(express);
let io = require('socket.io')(server);
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
io.on('connection', (socket) => {
console.log('User connected');
socket.emit('hello',{
greeting: 'Hello agam'
});
});
module.exports = router;
My angular code where i have included socket.io and calling my node server
import { Component, OnInit } from '#angular/core';
import * as socketIo from 'socket.io-client';
#Component({
selector: 'app-home-component',
templateUrl: './home-component.component.html',
styleUrls: ['./home-component.component.css']
})
export class HomeComponentComponent implements OnInit {
constructor() {
}
ngOnInit() {
const socket = socketIo('http://localhost:3000');
socket.on('hello', (data) => {
console.log(data);
});
}
}
The error which I am getting while running the app:
zone.js:2935 GET http://localhost:3000/socket.io/?
EIO=3&transport=polling&t=M4aQ8Fg 404 (Not Found)
This is My app.js :
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var cors = require('cors');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(cors({origin: true, credentials: true}));
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(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Add:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
...
// And at end of file
http.listen(3000, () => {
console.log('started on port 3000');
});
The basic problem is as follows:
Passing an object from my c# program, which is serialize and send through a socket. Achieved this in node.js/express application with socket.io.
Need to pass this to the client and using pug as the template engine.
Everything tried so far just doesn't seem to be working. Can't access the elements in the object. Pretty new to node and express so please bear with me.
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 routes = require('./app_server/routes/index');
var users = require('./app_server/routes/users');
var app = express();
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
// view engine setup
app.set('views', path.join(__dirname, 'app_server', '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);
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
// 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;
layout.jade :
doctype html
html
head
meta(name='viewport', content='width=device-width, initial-scale=1.0')
title= title
link(rel='stylesheet', href='/bootstrap/css/amelia.bootstrap.css')
link(rel='stylesheet', href='/stylesheets/style.css')
script(src="https://cdn.socket.io/socket.io-1.4.5.js")
script.
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
body
block content
script(src='/javascripts/jquery-1.11.1.min.js')
script(src='/bootstrap/js/bootstrap.min.js')
index.jade :
extends layout
block content
h1= title
p Welcome to #{title}
//THIS IS WHERE I DON'T KNOW HOW TO ACCESS THE OBJECT AND ITS PROPERTIES
Can see the object in the console so the data is appearing.
Tried many different variations, but nothing seems to be working. Any input or guidance would be welcome.
Thanks in advance.
I have a problem with Node.JS/Socket.IO/Express.JS and i didn't find any solution.
I use:
"express": "~4.10.6"
"socket.io": "1.2.1"
on Ubuntu Linux
My problem is that when I run the server and access localhost:3000/chat at the first run all works great but after a refresh/2/3/4 the messages inserted in chat duplicates. For one refresh, i have to identical message on one submit. For two refreshes, I have 3 identical message and so on. This behaviour began when i put the socket functionality in express.js routes folder.
P.S. I'm new to node.js/socket.io/express.js
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 routes = require('./routes/index');
var users = require('./routes/users');
var chat = require('./routes/chat');
var app = express();
// Socket IO Things
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
// END - Socket IO Things
// 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.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);
app.use('/chat', chat.random_function(io));
// 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;
server.listen('3000');
/routes/chat.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
module.exports = {
router: router,
random_function: function(io) {
return function(req, res){
res.sendFile(__dirname + '/index.html');
io.sockets.on('connection', function (socket) {
socket.on('send message', function (data) {
io.sockets.emit('new message', data);
});
});
}
}
};
Client side sockets (routes/index.html)
<html>
<head>
<title>Chat with socket.io and node.js</title>
<style>
#chat {
height: 500px;
}
</style>
</head>
<body>
<div id="chat"></div>
<form id="chat-message" action="">
<input size="35" id="message"></input>
<input type="submit"></input>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
var $messageForm = $('#chat-message');
var $messageBox = $('#message');
var $chat = $('#chat');
$messageForm.submit(function(e){
e.preventDefault();
socket.emit('send message', $messageBox.val());
$messageBox.val("");
});
socket.on('new message', function(data){
$chat.append(data + "<br>");
});
</script>
</body>
</html>
How can I handle this problem? Thanks in advance! I also checked the debugger and on server come 1/2/3/4/5 different packages each time.
You're creating & attaching new connection listener on each /chat request. Try moving it outside of random_function and perhaps creating separate socket instance for each connection/client.
(Edit) code added:
Try this (should work, but I didn't test it)
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 routes = require('./routes/index');
var users = require('./routes/users');
var chat = require('./routes/chat');
var app = express();
// Socket IO Things
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
socket.on('send message', function (data) {
io.sockets.emit('new message', data);
});
});
// END - Socket IO Things
// 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.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);
app.use('/chat', chat.random_function);
routes/chat.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
module.exports = {
router: router,
random_function: function(req, res){
res.sendFile(__dirname + '/index.html');
}
};
As stated in title, I'm trying to use socket.io 1.0.4 with express 4.2, and all /?EIO requests return 404.
Bellow there are my files:
./bin/www :
#!/usr/bin/env node
var debug = require('debug')('generated-express-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);
});
./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 app = express();
// Extras para Socket.io
// 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');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(require('less-middleware')(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
// Requests
app.get('/', function (req, res) {
res.render('index', { title: 'Express' });
});
// Socket requests
//
//io.on('connection', function (socket) {
// socket.emit('news', { hello: 'world' });
// socket.on('my other event', function (data) {
// console.log(data);
// });
//});
/// 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;
var server = require('http').createServer(app);
server.listen(app.get('port'), function(){
console.log('Express listening on port ' + app.get('port'));
});
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
I fiddled more with my files, and got it to work, here is how I got it to work:
./bin/www : Need to keep the require app.js, or it won't work.
#!/usr/bin/env node
//var debug = require('debug')('generated-express-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.emit('news', { hello: 'world' });
// socket.on('my other event', function (data) {
// console.log(data);
// });
//});
./app.js : All that was on www goes here, before the last export.
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 app = express();
// Extras para Socket.io
// 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');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(require('less-middleware')(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
// Requests
app.get('/', function (req, res) {
res.render('index', { title: 'Express' });
});
// Socket requests
//
//io.on('connection', function (socket) {
// socket.emit('news', { hello: 'world' });
// socket.on('my other event', function (data) {
// console.log(data);
// });
//});
/// 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 debug = require('debug')('generated-express-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.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
module.exports = app;
I used the express generator to gen the project, disabled the routes, as it seems that Socket.io won't support express routes.
So, one year later, and more node studies later, I found that the previous answer is quite incomplete, and may lead to sub-optimal usage of express. This is the more correct approach to use Node + Express + Socket.io without problems:
On /bin/www.js, replace var http = require('http'); with var server = require('http').Server(app);, and remove var server = http.createServer(app);
And that's it... Use your routes normally, place chats anywhere, no problems anymore.
Note: I left the old response unedited to preserve comments and such relevant and on context.