【问题标题】:Express route socket.io emit data not captured by clientExpress route socket.io 发出客户端未捕获的数据
【发布时间】:2018-07-13 12:52:21
【问题描述】:

我能够在我的 ExpressJS 路由文件中发出一个套接字。但是客户端javascript不会读取发出的数据。

server.js

var express = require('express');
var path = require('path');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var bodyParser = require('body-parser');


app.use(express.static(__dirname + '/node_modules'));
app.use("/css", express.static(__dirname + '/css'));
app.use("/js", express.static(__dirname + '/js'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.set('io', io);

var aws_router = require('./app/routes')(app);

server.listen(8080);

app/routes.js

var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var path = require('path');
var process = require('process');



var aws_router = function(app, io){

  app.get('/', function(req, res) {
    //need to read from database
    var socketio = req.app.get('io');
      var objShopper = "hello"
      console.log(objShopper)
      socketio.emit("viewdata", objShopper);
      res.sendFile(path.join(process.cwd() + '/index.html'));
  });
  return router;
}

module.exports = aws_router;

套接字发射部分工作正常,至少我没有看到任何错误并在控制台中输出 hello。但是当我尝试从客户端 JS 读取发出的数据时,我无法读取它。

client.js

$( document ).ready(function() {

    var socket = io.connect('http://localhost:8080');
    socket.on('viewdata', function (results) {
        console.log("read data");
        var objShopper = JSON.parse(results);
    });

});

"read data" 永远不会显示在控制台中。我错过了什么?

【问题讨论】:

    标签: javascript node.js sockets express


    【解决方案1】:

    您有时间问题。您正在尝试在连接之前发送到套接字。以下是事件的顺序:

    1. 浏览器从您的服务器请求http://yourdomain/
    2. / 的快速路由收到请求。
    3. 您获得io 实例并执行io.emit()
    4. 然后你发送 index.html 来满足浏览器的请求。
    5. 浏览器解析生成的文件
    6. 浏览器运行您的 Javascript,它与您的服务器建立 socket.io 连接。

    希望您可以看到第 6 步发生在第 3 步之后很长时间,或者换句话说,第 3 步发生在当前正在请求的页面甚至与您的服务器建立 socket.io 连接之前。因此,当您执行io.emit() 并遍历所有当前连接以将消息发送给所有连接时,当前正在请求的页面不在该列表中,因为它的连接尚未建立。用 Javascript 建立连接的页面甚至还没有发送到浏览器。


    在页面被请求时已知的数据应该被放入页面中。还没有 socket.io 连接,所以你不能把它发送到那里。如果您希望它出现在页面中,请在页面中发送。

    如果您不想将它放在初始页面中(出于某种原因),那么您可以让页面加载并运行,并让页面中的 Javascript 通过 Ajax 调用或何时从您的服务器请求数据您的 Javascript 使用 socket.io 连接到您的服务器并且服务器看到传入的 socket.io 连接,然后它可以发送数据(现在时间将正确,因为此时已建立 socket.io 连接)。

    【讨论】:

    • @nad - 在请求页面时已知的任何数据都应放入页面本身。或者,如果您真的想单独获取它,那么让客户端 Javascript 加载并运行,然后您可以通过 Ajax 调用从您的服务器请求数据,或者当服务器看到您与 socket.io 连接时,它可以向您发送数据然后通过socket.io。
    • @nad - 这回答了你的问题吗?
    【解决方案2】:

    除了 jfreind00 答案,我认为你应该在服务器端使用connection 事件,它会在客户端和服务器之间建立连接时被触发,然后你可以向服务器发送数据客户:

    var aws_router = function(app, io){
    
        app.get('/', function(req, res) {
    
            res.sendFile(path.join(process.cwd() + '/index.html'));
        });
    
    
        //make sure client and server are connected
        io.on('connection', function (socket) {
            var objShopper = "hello"
            console.log(objShopper)
            socketio.emit("viewdata", objShopper);
        });
    
    
        return router;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-09-30
      • 2014-11-07
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      • 2014-10-24
      • 2019-03-15
      • 2020-10-14
      • 1970-01-01
      相关资源
      最近更新 更多