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



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

服务器.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);

应用/路由.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;

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

客户端.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"永远不会显示在控制台中。我错过了什么?

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

  1. 浏览器从您的服务器请求 http://yourdomain/。
  2. 您的/快速路由将收到请求。
  3. 您获得io实例并执行io.emit()
  4. 然后发送索引.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 连接,因此时间现在是正确的)。

除了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;
}

最新更新