2

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.

1
  • 1
    Can you update the title of your question to characterize the issue you want help with, not the tools you are using? Commented Jun 29, 2017 at 22:43

2 Answers 2

1

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:&nbsp

    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;  
      });
Sign up to request clarification or add additional context in comments.

3 Comments

It seems a bit better I think... now the Client connected message is logged exactly 6 times when a client actually connects, and a few more times randomly as you wait
Thank you it works! I think my problem was that I was including socket.io on the client side using a cdn, rather than /socket.io/socket.io.js. Making that change fixed it.
I don't think so, cdn should also work fine. Replace /socket.io/socket.io.js with https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js and replace var socket = io(); with var socket = io("http://localhost:3000"); and everything is ok. The difference is that when you use cdn you have to specify the url of the server and if you use local socket.io the client "knows" the server address.
1

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.

2 Comments

In your 'app' and your 'www' js files, you are creating both an app and io server ref. My belief is that you are creating an infinite loop. Why both?
@jamesemanon I removed the extra references from app.js (code in original post updated) but I get the same thing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.