Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
610 views
in Technique[技术] by (71.8m points)

javascript - Express route socket.io emit data not captured by client

I am able to emit a socket in my ExpressJS route file. But that emitted data is not read by the client side 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;

The socket emit portion works fine, at least I see no error and output hello in the console. But when I try to read the emitted data from client side JS, I can't read it.

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. What am I missing?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.
  2. Your express route for / gets the request.
  3. You get the io instance and do io.emit().
  4. Then you send index.html to satisfy the browser request.
  5. The browser parses the resulting file
  6. Browser runs your Javascript which makes a socket.io connection to your server.

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. 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. Heck the page with the Javascript to make the connection hasn't even been sent to the browser yet.


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. 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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...