Javascript io.connect:未定义io,但已加载socket.io

Javascript io.connect:未定义io,但已加载socket.io,javascript,ajax,node.js,Javascript,Ajax,Node.js,我构建了一个node.js服务器,它提供了一个client.html页面,其中包含来自mysql数据库的消息列表。我无法使用ajax调用使其正常工作。 client.html页面如下所示: <time></time> <div id="container">Loading ...</div> <script src="http://oclock.dyndns.org:8000/socket.io

我构建了一个node.js服务器,它提供了一个client.html页面,其中包含来自mysql数据库的消息列表。我无法使用ajax调用使其正常工作。 client.html页面如下所示:

        <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>
socket.io代码已加载,但io.connect上出现错误:未定义io。如果将url从client.html更改为(正在侦听请求的node.js服务器的url),则会出现同样的问题。 感谢您的帮助

编辑: 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');

好吧,一开始我误解了。我刚刚调查了你的live应用程序,你的ajax调用似乎正在删除整个html文档

如果您是通过ajax加载标记,然后插入到现有页面中,那么您不需要完整的HTML文档。只需发送正文内容


另外,socket.io脚本引用最好位于父页面上,而不是通过ajax加载的页面上。

请同时发布服务器socket.io代码。完成,感谢帮助。当我导航到你的应用程序时,它似乎正在工作,不是吗?我可以在Chrome开发工具中看到socket.io已连接并正在刷新时间戳。现在,我尝试将结果集成到主应用程序索引页面中。应用程序正在端口80上运行。试试看,我正在使用oclock.dyndns.org:8000/socket.io/socket.io.js“>因为从端口80上的页面,我正在请求8000上的资源,并且socket.io.js已加载(正如我在firebug中看到的)关键是套接字代码已加载但未使用。如果我在ajax中使用url并在浏览器中的新窗口中传递url,则会起作用。请查看我编辑的答案。您不希望将完整的HTML文档粘贴到现有的HTML文档中。服务器上的端点应返回可插入现有DOM的HTML片段。您只需如果您将浏览器直接指向该标记以加载整页,则不会将其视为完整文档。目前还不确定它是否会修复
io
引用,但如果将完整HTML文档粘贴到现有页面中会导致某些问题,我也不会感到惊讶。是的,client.HTML代码将被“清除”“所有不必要的物品。请您解释一下“socket.io脚本引用最好在父页面上,而不是通过ajax加载的页面上”是什么意思?非常感谢您的帮助:)那些通过ajax加载的文档附带的
标记。这些应该在父页面上(进行ajax调用的页面)。
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');