这是我的堆栈:
iOS和Android应用
DocumentDB
由Javascript支持的移动服务
由Javascript支持的Azure网站
我们要做的是从我们的应用程序中抽象出DocumentDB的知识,因为我们正在构建白标解决方案,我们可能需要即时扩展DocumentDB实例。使用抽象类型的服务,我们基本上可以根据应用程序发送的某些数据对我们的docdb实例进行分片。
现在,这将包含2个我想为其创建移动服务的操作。一个用于获取JSON数据,另一个用于获取与文档关联的附件。这是我的麻烦所在。我有一个可部署的NodeJS编写的传递服务。我喜欢与移动服务相关的安全模型,所以我想调整我的代码。问题在于管理DocDB对移动服务响应的响应。首先是移动服务默认标头试图设置和失败,所以我暂时覆盖该功能。现在,移动服务永远不会响应,直到发生超时。这是一段代码:
exports.get = function (req, res) {
...
// .then().fail() always pushed into the fail() block, but if I use the 2 function in .then() way it works.
client.readMediaAsync(mediaUrl).then(
// Success
function (media) {
// Set up caching and proxy the response
media.headers["cache-control"] = "max-age=2147483647, max-stale=2147483647";
media.headers["pragma"] = "cache";
for (var responseHeader in media.headers) {
if (media.headers.hasOwnProperty(responseHeader) && "content-location" != responseHeader) {
res.setHeader(responseHeader, media.headers[responseHeader]);
}
}
// Block further header modification
res.setHeader = function(field, val){};
media.result.pipe(res, {end: true});
//media.result.on("end", function () {
// console.log("attachment#end");
// res.status(200).send(); // have also tried .end() with no luck
//});
},
// Error
function (mediaError) {
console.error("documentClient.readMediaAsync fail->" + JSON.stringify(mediaError));
res.status(400).send(JSON.stringify(mediaError));
}
); ...
读取media.result.pipe(...)的行是挂断的地方。同样,此代码在移动服务之外工作。我一直在使用这个改变 - >提交 - >测试 - >重复循环,但没有运气。有人知道如何在流媒体服务中正确地将流传输到响应中吗?
答案 0 :(得分:0)
我成功地重现了你的问题,我在请求一段时间后得到了HTML代码,但是我在LOGS选项卡中也收到了错误消息,它看起来像:
An unhandled exception occurred. Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (http.js:679:11) at ServerResponse.res.setHeader (D:\home\site\wwwroot\node_modules\express\node_modules\connect\lib\patch.js:59:22) at ServerResponse.res.set.res.header (D:\home\site\wwwroot\node_modules\express\lib\response.js:518:10) at addDefaultHeaders (D:\home\site\wwwroot\runtime\request\requesthandler.js:582:9) at ServerResponse.<anonymous> (D:\home\site\wwwroot\runtime\request\requesthandler.js:291:13) at ServerResponse._.wrap [as end] (D:\home\site\wwwroot\node_modules\underscore\underscore.js:692:22) at onend (stream.js:66:10) at EventEmitter.emit (events.js:126:20) at afterRead (fs.js:1335:12) at Object.wrapper [as oncomplete] (fs.js:367:17)
根据这个日志,我在管道之前将头部设置为响应,并且在我的测试中工作正常。
这是我的简单代码段:
exports.get = function(request, response) {
var fs = require("fs");
response.setHeader = function(field, val){};
fs.createReadStream('files/123.txt').pipe(response,{end: true});
};
答案 1 :(得分:0)
我通过使用节点documentdb sdk的非承诺版本解决了这个问题。必须有一些东西在答案中与承诺相混淆(虽然它看起来非常简单)。
以下是正常运行的代码段:
clientSync.readMedia(mediaUrl, function (err, mediaStream) {
if (!err && mediaStream) {
mediaStream.headers["cache-control"] = "max-age=2147483647, max-stale=2147483647";
mediaStream.headers["pragma"] = "cache";
for (var responseHeader in mediaStream.headers) {
if (mediaStream.headers.hasOwnProperty(responseHeader) && "content-location" != responseHeader) {
res.setHeader(responseHeader, mediaStream.headers[responseHeader]);
}
}
res.setHeader = function (field, val) {
};
mediaStream.pipe(res);
mediaStream.on('end', function () {
res.status(200).end();
});
} else {
console.error("attachment(" + mediaUrl + ") catch->" + JSON.stringify(err.detail) + "; " + err.message + "; " + err.stack);
res.status(400).send();
}
});