简体   繁体   English

快速路由socket.io发出客户端未捕获的数据

[英]Express route socket.io emit data not captured by client

I am able to emit a socket in my ExpressJS route file. 我可以在ExpressJS路由文件中发出套接字。 But that emitted data is not read by the client side javascript. 但是客户端的javascript无法读取发出的数据。

server.js 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 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;

The socket emit portion works fine, at least I see no error and output hello in the console. 套接字发出部分工作正常,至少我没有看到错误,并在控制台中输出了hello。 But when I try to read the emitted data from client side JS, I can't read it. 但是,当我尝试从客户端JS读取发出的数据时,我无法读取它。

client.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" is never shown in the console. 控制台中永远不会显示"read data" What am I missing? 我想念什么?

You have a timing issue. 您有时间问题。 You're trying to send to the socket before it's connected. 您正在尝试在连接之前发送到套接字。 Here's the sequence of events: 这是事件的顺序:

  1. Browser requests http://yourdomain/ from your server. 浏览器从您的服务器请求http:// yourdomain /
  2. Your express route for / gets the request. 您的快递路线/获得请求。
  3. You get the io instance and do io.emit() . 您将获得io实例并执行io.emit()
  4. Then you send index.html to satisfy the browser request. 然后,您发送index.html以满足浏览器请求。
  5. The browser parses the resulting file 浏览器解析结果文件
  6. Browser runs your Javascript which makes a socket.io connection to your server. 浏览器运行您的Javascript,该Javascript与服务器建立socket.io连接。

Hopefully you can see that step 6 happens long after step 3 or put another way, step 3 happens before the page that is currently being requested even has a socket.io connection to your server. 希望您可以看到第6步发生在第3步之后很长时间,或者换句话说,第3步发生在当前请求的页面甚至与服务器的socket.io连接之前。 Thus, when you do io.emit() and it iterates through all current connections to send the message to all of them, the page that is currently being requested is not in that list because it's connection has not been made yet. 因此,当您执行io.emit()并遍历所有当前连接以将消息发送给所有这些连接时,当前请求的页面不在该列表中,因为尚未建立连接。 Heck the page with the Javascript to make the connection hasn't even been sent to the browser yet. 用Java语言编写页面,以使连接尚未发送到浏览器。


Data that is known at the time the page is being requests should just be put into the page. 在请求页面时已知的数据应仅放入页面中。 There's no socket.io connection yet so you can't send it there. 目前尚无socket.io连接,因此您无法将其发送到那里。 If you want it to be in the page, send it in the page. 如果您希望它出现在页面中,请在页面中发送它。

If you don't want to put it in the initial page (for some reason), then you can let the page load and run and have the Javascript in the page request the data from your server via an Ajax call or when your Javascript connects to your server with socket.io and the server sees the incoming socket.io connection, it can send the data then (the timing will now be correct since the socket.io connection is established at this point). 如果不想(由于某种原因)将其放在初始页面中,则可以让页面加载并运行,让页面中的Javascript通过Ajax调用或Javascript连接从服务器请求数据使用socket.io连接到您的服务器,并且服务器看到传入的socket.io连接,然后可以发送数据(由于此时已经建立了socket.io连接,因此时间现在是正确的)。

Beside jfreind00 answer, I think you should use connection event in the server side, it will be fired when the connection is established between client and server, and then you could emit data to the client: 除了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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM