simple express and socket example does not work - node.js

i use express 4 with socket.io.
when server is running, socket does not work.
console does not print 'user connect'.
client button does not work.
please help me. :-(
this is my code
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 app = express();
// 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.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
// 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;
io.js
var io = require('socket.io')();
io.on('connection', function(socket) {
console.log('user connected');
socket.on('rint', function(data) {
console.log('user send data : ' + data);
socket.emit('smart', data);
});
});
module.exports = io;
/bin/www
\#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var io = require('../io');
var debug = require('debug')('socketT: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);
io.attach(server);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
...
index.html
<!DOCTYPE html>
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script>
window.onload = function() {
var socket = io();
socket.on('smart', function(data) {
alert(data);
});
document.getElementById('button').onclick = function() {
var text = document.getElementById('text').value;
socket.emit('rint', text);
});
});
</script>
</head>
<body>
<input type="text" id="text" />
<input type="button" id="button" value="echo" />
</body>
</html>

Your listener for everything on the server-side is on("connection", ... but you don't make that connection anywhere on the client side.
Check out the following page: http://socket.io/docs/
You will need to add the url of the server you are connecting:
index.html:
var socket = io("localhost:8080"); //Or whatever your url and port are.

Related

Run socket.io 2.0 and Express 4.0+ on the same port

I have installed socket.io before on a Node project without the need of express templating framework.
Issue
if I add this line of code: http.listen(3001, function() { console.log('listening on port 3001'); }); then on visiting localhost:3000 I have my app in which sockets does not work and on localhost:3001 I have sockets working. How do I merge both of these?
Error
socket.io.js:2 GET http://localhost:3000/socket.io/?EIO=3&transport=polling&t=LpQ6zKP net::ERR_CONNECTION_REFUSED
I am trying to add socket.io in express framework like below:
app.js file
const express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var expressValidator = require('express-validator');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var bodyParser = require('body-parser');
var flash = require('connect-flash');
var multer = require('multer');
var upload = multer({ dest: './uploads' });
var mongo = require('mongodb');
var mongoose = require('mongoose');
var db = mongoose.connection;
var index = require('./routes/index');
var app = express();
var http = require( "http" ).createServer( app );
var io = require( "socket.io" )( http );
http.listen(3000, "127.0.0.1");
var httpk = require('http');
var nsp = io.of('/channel1');
var connectCounter = 0;
var interval = undefined;
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use('/js', express.static(__dirname + '/node_modules/bootstrap/dist/js')); // redirect bootstrap JS
app.use('/js', express.static(__dirname + '/node_modules/jquery/dist')); // redirect jQuery JS
app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css')); // redirect Bootstrap CSS
// 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 }));
//Handle express sessions
app.use(session({
secret:'secret',
saveUninitialized: true,
resave:true
}));
// Passport
app.use(passport.initialize());
app.use(passport.session());
// Validator
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
//For flash messages
app.use(flash());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
app.get('*', function(req, res, next){
res.locals.user = req.user || null;
next();
});
app.use('/', index);
function test() {
httpk.get("api-url", function(res) {
var body = '';
res.on('data', function(data) {
body += data;
});
res.on('end', function() {
var parsed = JSON.parse(body);
//console.log(parsed.data.product1);
var dataArray = [];
dataArray.push((parseFloat(parsed.data.product1) + Math.random() * 0.1 + 0.01).toFixed(2));
dataArray.push((parseFloat(parsed.data.product2) + Math.random() * 0.1 + 0.01).toFixed(2));
console.log(dataArray);
nsp.emit('live-quote', dataArray);
});
});
}
nsp.on('connection', function(socket) {
socket.on('pass_data', function(my) {
console.log(my);
});
//Make a http call
connectCounter++;
if (interval === undefined) interval = setInterval(test, 1000);
nsp.emit('live-users', connectCounter);
console.log('1 user connected, Total Joined: ' + connectCounter);
socket.on('disconnect', function() {
connectCounter--;
if (connectCounter <= 0 && interval !== undefined) interval = clearInterval(interval);
nsp.emit('live-users', connectCounter);
console.log('1 user disconnected, Total Left: ' + connectCounter);
});
console.log("total clients: " + io.engine.clientsCount);
});
// 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;
head.ejs
<title><%= title %></title>
<link rel="stylesheet" href="/css/bootstrap.min.css">
<script src="/js/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
<link rel='stylesheet' href='/stylesheets/style.css' />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" >
jsdefaults.ejs
<script src="/javascripts/script.js" ></script>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function() {
var socket = io('/channel1');
var currentTime;
socket.on('live', function(msg) {
console.log("msg: "+msg);
});
socket.on('live-users', function(users) {
$('#total').text(users);
});
});
</script>
index.ejs
<!DOCTYPE html>
<html>
<head><% include partials/head.ejs %></head>
<body>
<% include partials/header.ejs %>
<div class="container" style="margin-top:20px;">
</div>
<% include partials/footer.ejs %>
<% include partials/jsdefaults.ejs %>
</body>
</html>
It looks like you used express-generator to set up your Express application, in which case the HTTP server will be set up in bin/www and that's where the socket.io server should be set up as well (since you want to share the HTTP server between Express and socket.io).
The default bin/www contains this:
/**
* Create HTTP server.
*/
var server = http.createServer(app);
That's where you add the socket.io server:
var server = http.createServer(app);
var io = require('socket.io')(server);
var nsp = io.of('/channel1');
nsp.on('connection', ...);

How do I emit the data asynchronously from server to client in socket.io

Here I'm emitting the data from app.js to index.html page.But I'm not getting the asynchronous data.
Here I'm trying to download a file and try to send the download progress to the index.html.But in "index.html",I'm getting the data once the download is complete.I don't want this to happen.
If the file is downloaded 40% then the same should display in the browser also.How can I achieve this? Can anyone please help me out ...
My 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 fs = require('fs');
var request = require('request');
var progress = require('request-progress');
var DOWNLOAD_DIR = '/usr/local/';
var file_name = 'jquery.js'
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express ();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
http.listen(8085, function(){
console.log('listening on *:8085');
});
// 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);
app.get('/get', function (req, res) {
progress(request('https://jqueryjs.googlecode.com/files/jquery-1.3.2-vsdoc2.js'), {
throttle:0,
delay: 0
})
.on('progress', function(state){
console.log('received size in bytes', state.received);
console.log('total size in bytes', state.total);
console.log('percent', state.percent);
io.of('/socket_issue').on('connection', function (socket) {
console.log("Socket connected :"+socket.id);
socket.emit('message', JSON.stringify({size: state.total, received: state.received, percent: state.percent, fileName: file_name}));
});
})
.pipe(fs.createWriteStream(DOWNLOAD_DIR + file_name))
.on('error', function (err) {
console.log("error");
})
.on('close', function (err){
console.log("Download Complete");
});
res.sendfile('views/index.html');
});
// 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;
My index.html :
<html>
<body>
<script src="http://localhost:8085/javascripts/socket.js"></script>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://localhost:8085/javascripts/bootstrap.js"></script>
<script src="http://localhost:8085/javascripts/bootstrap-progressbar.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link href="http://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="http://localhost:8085/stylesheets/bootstrap.css" />
<div id="progressbar"><div>
<script type="text/javascript">
var socket = io('http://localhost:8085/socket_issue');
socket.on('connect', function(){ console.log('connected to socket'); });
socket.on('error', function(e){ console.log('error' + e); });
socket.on('message', function(data){
console.log(data);
function progress(percent, $element) {
var progressBarWidth = percent * $element.width() / 100;
$element.find('div').animate({ width: progressBarWidth }, 500).html(percent + "% ");
}
progress(JSON.parse(data).percent, $('#progressbar'));
});
socket.on('disconnect', function(){});
</script>
</body>
</html>
In index.html (edited)
<body onload="timedRefresh(10000);">
<script type="text/javaScript">
function timedRefresh(timeoutPeriod) {
setTimeout("window.location.reload(true);",timeoutPeriod);
}
</script>
you're downloading a 200kb file on the server...your client has far more to load. jquery-ui alone, for example, is over 400 kilobytes. So the server is probably done downloading the file before the client even has the opportunity to connect and listen for download progress.
As a side note, I'd recommend you move io.of('socket_issue').on... outside of the .on('progress' event. It doesn't make sense to start listening for socket.io connections every time someone requests /get

How to link app.js to html page,so that I should display the progress bar in the browser using socket.io

I'm unable to link the index.html page to app.js.I'm trying to send the progress to index.html.But,I'm failing here.How can I overcome this issue?Can anyone please help me out ...
My index.html :
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="bootstrap.js"></script>
<link rel="stylesheet" type="text/css" href="bootstrap.css" />
<div id="progressbar">
</div>
<script>
var socket = io('http://localhost:8085');
socket.on('connect', function(){});
socket.on('message', function(data){
$('#progressbar').progressbar({
maximum: 100,
step: JSON.parse(data).percent
});
});
socket.on('disconnect', function(){});
</script>
My app.js :
var fs = require('fs');
var request = require('request');
var progress = require('request-progress');
var DOWNLOAD_DIR = '/usr/local/';
var file_name = 'googlenew.png'
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express ();
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.listen(8085, function(){
console.log('listening on *:8085');
});
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
console.log("connected :"+socket.id);
});
var callback = function(state){
console.log('received size in bytes', state.received);
console.log('total size in bytes', state.total);
console.log('percent', state.percent);
io.sockets.emit('message', JSON.stringify({size: state.total, received: state.received, percent: state.percent, fileName: file_name}));
}
progress(request('https://www.google.com/images/srpr/logo3w.png'), {
throttle:0,
delay: 0
})
.on('progress', callback)
.pipe(fs.createWriteStream(DOWNLOAD_DIR + file_name))
.on('error', function (err) {
console.log("error");
})
.on('close', function (err){
console.log("Download Complete");
})
Updated 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 fs = require('fs');
var request = require('request');
var progress = require('request-progress');
var DOWNLOAD_DIR = '/usr/local/';
var file_name = 'googlenew.png'
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
var server = app.listen(8085, function(){
console.log('listening on *:8085');
});
var io = require('socket.io')(server);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
console.log("connected :"+socket.id);
});
var callback = function(state){
console.log('received size in bytes', state.received);
console.log('total size in bytes', state.total);
console.log('percent', state.percent);
io.sockets.emit('message', JSON.stringify({size: state.total, received: state.received, percent: state.percent, fileName: file_name}));
}
progress(request('https://www.google.com/images/srpr/logo3w.png'), {
throttle:0,
delay: 0
})
.on('progress', callback)
.pipe(fs.createWriteStream(DOWNLOAD_DIR + file_name))
.on('error', function (err) {
console.log("error");
})
.on('close', function (err){
console.log("Download Complete");
})
// 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);
// 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;
You are not initializing Express properly so app is not hooked to any web server and thus app.get() isn't active.
Change this:
var app = express ();
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.listen(8085, function(){
console.log('listening on *:8085');
});
to this:
var app = express();
var server = app.listen(8085, function(){
console.log('listening on *:8085');
});
var io = require('socket.io')(server);
See the basic "Hello World" app example in the ExpressJS doc.
And, you will also need to make routes for jquery.js, bootstrap.js, etc... Remember, node.js doesn't serve any files by default. Since they are static files, you will probably want to use app.use(express.static(...)) to serve the static files.

express js - socket io connection

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");
});
});

Socket.io Chat Application Refreshes When I Send a Message

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() { ... });

Resources