Lelio Faieta
Lelio Faieta

Reputation: 6684

io.connect: io is not defined but socket.io is loaded

I have built a node.js server that provides a client.html page with a list of messages from a mysql db. I can't make it work using an ajax call. The client.html page is this:

        <time></time>
        <div id="container">Loading ...</div>
        <script src="http://oclock.dyndns.org:8000/socket.io/socket.io.js"></script>
        <!--<script src="socket.io/socket.io.js"></script>-->
        <script src="http://code.jquery.com/jquery-latest.min.js"></script>
        <script>

        // create a new websocket
        var socket = io.connect('http://oclock.dyndns.org:8000');
        // on message received we print all the data inside the #container div
        socket.on('notification', function (data) {
        var msgs = '<div>';
        $.each(data.flashmsgs,function(index,flashmsg){
            msgs += "<b>Messaggio inviato da " + flashmsg.created_by + "</b><br>";
            msgs += flashmsg.testo;
        });
        msgs += '</div>';
        $('#container').html(msgs);

        $('time').html('Last Update:' + data.time);
      });
    </script>

and the code for the ajax call is the following:

    (function nodeLoader(){
        $.ajax({
            url: "client.html",
            method: "get",
            data: {hk: hk },
            success: function(data){
                $('#messaggi').html(data);
            }
        });
    })();

The socket.io code is loaded but I get an error on io.connect: io is not defined. Same issue if i change the url from client.html to http://oclock.dyndns.org:8000 (the url of the node.js server that is listening for requests). Any help is appreciated!

EDIT: server.js

var hwkey;
var app = require('http').createServer(handler),
  io = require('socket.io').listen(app),
  url = require('url'),
  fs = require('fs'),
  mysql = require('mysql'),
  connectionsArray = [],
  connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'flipper',
    database: 'oclock',
    port: 3306
  }),
  POLLING_INTERVAL = 3000,
  pollingTimer;

// If there is an error connecting to the database
connection.connect(function(err) {
  // connected! (unless `err` is set)
  if (err) {
    console.log(err);
  }
});

// creating the server ( localhost:8000 )
app.listen(8000);


function handler(req, res) {
    var origin = (req.headers.origin || "*");
    if (req.method.toUpperCase() === "OPTIONS"){
      res.writeHead(
          "204",
          "No Content",
          {
              "access-control-allow-origin": origin,
              "access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS",
              "access-control-allow-headers": "content-type, accept",
              "access-control-max-age": 10, // Seconds.
              "content-length": 0
          }
      );
      return( res.end() );
    }

    console.log("INCOMING REQUEST: "+req.method+" "+req.url);
    req.parsed_url = url.parse(req.url, true);
    var getp = req.parsed_url.query;
    hwkey = getp.hk;

    fs.readFile(__dirname + '/client.html', function(err, data) {
    if (err) {
      console.log(err);
      res.writeHead(500);
      return res.end('Error loading client.html');
    }
    res.writeHead(
                  200,
                    {
                        "access-control-allow-origin": origin,
                        "content-length": data.length
                    }
                  );
    res.end(data);
  });
}


function pollingLoop(){
  // Doing the database query
  var query = connection.query('SELECT id, testo, created_by FROM flashmsgs WHERE hwk="'+hwkey+'" AND letto="0"'),
  //var query = connection.query('SELECT max(id), testo, created_by FROM flashmsgs'),
    flashmsgs = []; // this array will contain the result of our db query

  // setting the query listeners
  query
    .on('error', function(err) {
      // Handle error, and 'end' event will be emitted after this as well
      console.log(err);
      updateSockets(err);
    })
    .on('result', function(flashmsg) {
      // it fills our array looping on each user row inside the db
      flashmsgs.push(flashmsg);
    })
    .on('end', function() {
      // loop on itself only if there are sockets still connected
      if (connectionsArray.length) {

        pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);

        updateSockets({
          flashmsgs: flashmsgs
        });
      } else {

        console.log('The server timer was stopped because there are no more socket connections on the app')

      }
    });
};


// creating a new websocket to keep the content updated without any AJAX request
io.sockets.on('connection', function(socket) {

  console.log('Number of connections:' + connectionsArray.length);
  // starting the loop only if at least there is one user connected
  if (!connectionsArray.length) {
    pollingLoop();
  }

  socket.on('disconnect', function() {
    var socketIndex = connectionsArray.indexOf(socket);
    console.log('socketID = %s got disconnected', socketIndex);
    if (~socketIndex) {
      connectionsArray.splice(socketIndex, 1);
    }
  });

  console.log('A new socket is connected!');
  connectionsArray.push(socket);

});

var updateSockets = function(data) {
  // adding the time of the last update
  data.time = new Date();
  console.log('Pushing new data to the clients connected ( connections amount = %s ) - %s', connectionsArray.length , data.time);
  console.log(hwkey);
  // sending new data to all the sockets connected
  connectionsArray.forEach(function(tmpSocket) {
    tmpSocket.volatile.emit('notification', data);
  });
};

console.log('Please use your browser to navigate to http://localhost:8000');

Upvotes: 1

Views: 632

Answers (1)

ChevCast
ChevCast

Reputation: 59231

Okay, I misunderstood at first. I just investigated your live app and it appears your ajax call is pulling down an entire html document.

If you're loading markup via ajax and then inserting into the existing page, you don't want a full HTML document. Just send down the body content.

Also, the socket.io script reference should ideally be on the parent page, not the page loaded via ajax.

Upvotes: 1

Related Questions