2

所以,我有一个如下的路由函数:

var http = require('http').createServer(start);

function start(req, res){
//routing stuff
}

在此之下,我有一个 socket.io 事件监听器:

io.sockets.on('connection', function(socket){

    socket.on('event', function(data){
        //perform an http response
    }

}

当调用套接字事件“事件”时,我想执行如下的 http 响应:

res.writeHead(200, {'Content-disposition': 'attachment; filename=file.zip'})
res.writeHead(200, { 'Content-Type': 'application/zip' });
var filestream = fs.createReadStream('file.zip');

filestream.on('data', function(chunk) {
    res.write(chunk);
});

filestream.on('end', function() {
    res.end();
});

最后一部分,当在路由函数中执行时工作得很好,但不幸的是,当它从套接字事件调用时,它当然不起作用,因为它没有引用“req”或“res”对象。我该怎么做呢?谢谢。

4

1 回答 1

2

嗯...有趣的问题:

  • 做你想做的事情并非不可能,流程是这样的:

    1. 接收 http 请求,不响应,将res对象保存在某处。
    2. 接收 websocket 请求,将您的身份验证/“链接”到res之前保存的对象。
    3. 通过文件响应res
  • 但它不是很漂亮,原因如下:

    1. 您需要保存 res 对象,如果您的服务器重新启动,则会丢失一大堆响应对象。
    2. 您需要弄清楚如何将 websocket 客户端链接到 http 请求客户端。我认为您可以使用 cookie/localstorage 来执行此操作。
    3. 扩展到另一台服务器将变得更加困难/您是否会代理客户端以某种方式始终由同一台服务器提供服务?否则链接将变得更加困难。

我会为您提出一个不同的解决方案:您想在让某人下载文件之前使用 websockets 执行一些客户端/服务器步骤吗?

  • 这个问题有一个通过 websocket 进行下载的解决方案:通过 websocket接收文件并启动下载对话框

    • 听起来它不适用于较旧的浏览器/ IE,但这是一个不错的选择。
    • 还提到通过隐藏的 iframe 下载

在此处检查此解决方案是否适合您的跨浏览器:http: //caniuse.com/#feat=datauri

另一种选择是为下载生成一个唯一的 URL,并且仅在您通过 websocket 完成逻辑后将其附加到浏览器的窗口(作为隐藏的 iframe 下载或作为简单的下载按钮)。此选项将更易于跨浏览器使用并且更易于编码。

于 2012-11-10T23:47:39.687 回答