移动服务+ DocumentDB附件

这是我的堆栈:

  • iOS和Android应用程序

  • DocumentDB

  • 由Javascript支持的移动服务

  • 由Javascript支持的Azure站点

我正在做的是从我们的应用程序中抽象出DocumentDB的知识,因为我们正在构build白色标签解决scheme,而且我们可能需要即时扩展DocumentDB实例。 使用抽象types的服务,我们基本上可以根据从应用程序发送的某些数据来分割我们的docdb实例。

现在这将包括2个我想要创build移动服务的操作。 一个获取JSON数据,另一个获取与文档关联的附件。 这是我的麻烦所在。 我有一个只能在NodeJS中部署的传递服务。 我喜欢与移动服务相关的安全模型,所以我想调整我的代码。 问题在于将DocDB响应传递给移动服务响应。 首先是移动服务默认标题试图设置和失败,所以我暂时覆盖该function。 现在移动服务从不响应,直到发生超时。 这是一个代码片段:

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(…)的行是挂起的地方。 再次,这个代码在移动服务之外工作。 我一直在使用更改 – >提交 – >testing – >重复循环,但没有任何运气。 是否有人知道如何在移动服务中正确地将stream传输到响应中?

我成功地重现了您的问题,请求了一段时间后我得到了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)

根据这个日志,我在pipe之前设置了header,并在我的testing中正常工作。

这里是我简单的代码片段: exports.get = function(request, response) { var fs = require("fs"); response.setHeader = function(field, val){}; fs.createReadStream('files/123.txt').pipe(response,{end: true}); }; exports.get = function(request, response) { var fs = require("fs"); response.setHeader = function(field, val){}; fs.createReadStream('files/123.txt').pipe(response,{end: true}); };

我通过使用节点documentdb sdk的非承诺版本解决了这个问题。 在承诺答复中必然会混杂起来(虽然看起来相当简单)。

这是function代码片段: 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(); } });