我想在长时间结束后向客户端发出事件。 这将在客户端显示带有链接的隐藏div。
这是我测试过的方法:
// server.js
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
require('./app/routes.js')(app, io);
// routes.js
app.post('/pst', function(req, res) {
var url = req.body.convo;
res.render('processing.ejs');
myAsyncFunction(url).then(result => {
console.log('Async Function completed');
socket.emit('dlReady', { description: 'Your file is ready!'});
//do some other stuff here
}).catch(err => {
console.log(err);
res.render('error.ejs');
})
});
我明白了
ERROR: ReferenceError: socket is not defined
如果我将socket.emit()行更改为此:
io.on('connection', function(socket) {
socket.emit('dlReady', { description: 'Your file is ready!'});
});
然后我没有收到任何错误,但是客户端没有任何反应。
这是客户端代码:
<script>
document.querySelector('.container2').style.display = "none";
var socket = io();
socket.on('dlReady', function(data) { //When you receive dlReady event from socket.io, show the link part
document.querySelector('.container1').style.display = "none";
document.querySelector('.container2').style.display = "block";
});
</script>
答案 0 :(得分:1)
整个概念可能有点瑕疵。让我陈述一些有关此环境的事实,您必须完全了解这些事实,然后才能了解发生的情况:
res.render()
发送回信时,浏览器将关闭上一页并呈现新页面。res.render()
中的新页面中包含Javascript,则当该Javascript运行时,它可能会或可能不会与服务器创建新的socket.io连接。无论如何,只有在调用res.render()
之后的一段时间,这种情况才会发生,因为浏览器必须接收新页面,解析它,然后运行其中的Javascript,然后再将socket.io连接到您的服务器。socket.emit()
的服务器范围的变量并使用它来执行此操作。多用户服务器永远无法做到这一点。因此,我对您的问题的理解是,您希望从客户端获取POST表格,将呈现的socket
返回客户端,然后稍后再与您进行交流通过socket.io在客户端呈现页面。为此,必须执行以下步骤。
processing.ejs
来完成。我建议您使用express-session
,因为它可以简化以下步骤,并且假设您正在使用express-session
,我将概述步骤。express-session
放入会话对象中的顶级io.on('connection', ...)
。因为客户端可以从多个选项卡进行连接,所以如果您不希望这样做引起麻烦,则可能必须在会话对象中维护一组套接字。socket
处理程序,以便在断开连接时将套接字从存储在其中的会话对象中删除。socket.on('disconnect', ...)
处理程序中,当您准备发送app.post()
消息时,必须在该页面的会话对象中为该浏览器找到合适的dlready
并发出到那个插座。如果由于您呈现的页面尚未连接而没有连接,则必须等待它连接(要有效地执行此操作很棘手)。如果POST请求来自页面中的Javascript,而不是来自表单发布,则事情会稍微简单一些,因为浏览器不会关闭当前页面并启动新页面,因此当前的socket.io连接将保持联系。如果需要,您仍然可以使用客户端Javascript完全更改页面外观。我会推荐这个选项。