无法 plotly + node.js 流式传输来自 POST 请求的数据
Can't get plotly + node.js to stream data coming through POST requests
我正在尝试通过向 http://localhost:3000/step
.
发送 POST
请求,以流式传输我的服务器接收到的数据
基于 plotly-nodejs/examples 中的 rest-example.js
,这是我的服务器代码(我模糊了我的用户名、apikey 和令牌):
'use strict';
var express = require('express');
var logger = require('morgan');
var bodyParser = require('body-parser');
var events = require('events');
var eventEmitter = new events.EventEmitter();
var app = express();
var server = require('http').Server(app);
var port = process.env.PORT || 3000;
server.listen(port);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/step', function(req, res) {
var data = req.body.data;
eventEmitter.emit('step', data);
res.end('ok');
});
var plotly = require('plotly')('username', 'apikey');
var token = 'token';
var dataInit = [{x:[], y:[], stream: { token: token, maxpoints: 10 } }];
var layout = {fileopt : "extend", filename : "REST-test"};
plotly.plot(dataInit, layout, function (err, msg) {
if(err) return console.error('step data error', err.stack);
var stream = plotly.stream(token, function() {});
eventEmitter.on('step', function(data) {
console.log('sending to plotly: ' + data + ' steps');
var streamObject = JSON.stringify({ x: getDateString(), y: data });
stream.write(streamObject+'\n');
});
});
function getDateString() {
var d = new Date();
return d.toLocaleString();
};
当我使用 cURL POST
数据时,例如 curl http://localhost:3000/step --data "data=5"
,我可以看到数据到达 plotly.plot
块内的回调,但 plotly 永远不会启动并流式传输数据。
在我之前处理的一些稍微复杂的服务器代码中,我也得到了可能相关也可能不相关的错误,它总是指向 plotly.plot
块的开头。
cb(null, body);
^
SyntaxError: Unexpected end of input
这是完整的错误堆栈:
/home/plotly-testing/node_modules/plotly/index.js:305
cb(null, body);
^
SyntaxError: Unexpected end of input
at Object.parse (native)
at /home/plotly-testing/node_modules/plotly/index.js:72:25
at IncomingMessage.<anonymous> (/home/plotly-testing/node_modules/plotly/index.js:305:9)
at IncomingMessage.emit (events.js:129:20)
at _stream_readable.js:908:16
at process._tickCallback (node.js:355:11)
---------------------------------------------
at IncomingMessage.Readable.on (_stream_readable.js:671:33)
at parseRes (/home/plotly-testing/node_modules/plotly/index.js:304:9)
at ClientRequest.<anonymous> (/home/plotly-testing/node_modules/plotly/index.js:71:9)
at ClientRequest.emit (events.js:107:17)
at HTTPParser.parserOnIncomingClient (_http_client.js:426:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:111:23)
at TLSSocket.socketOnData (_http_client.js:317:20)
---------------------------------------------
at new ClientRequest (_http_client.js:93:10)
at Object.exports.request (http.js:49:10)
at Object.exports.request (https.js:136:15)
at Plotly.plot (/home/plotly-testing/node_modules/plotly/index.js:70:21)
at Object.<anonymous> (/home/plotly-testing/index.js:175:8)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
plotly/index.js
的第 305 行指向以下方法,这似乎表明我的回调之一有问题,但我不确定。
// response parse helper fn
function parseRes (res, cb) {
var body = '';
if ('setEncoding' in res) res.setEncoding('utf-8');
res.on('data', function (data) {
body += data;
if (body.length > 1e10) {
// FLOOD ATTACK OR FAULTY CLIENT, NUKE REQ
res.connection.destroy();
res.writeHead(413, {'Content-Type': 'text/plain'});
res.end('req body too large');
return cb(new Error('body overflow'));
}
});
res.on('end', function () {
cb(null, body);
});
}
所以我修改了代码以在 Plotly.plot
回调中包含一个 console.log
。
在这里查看要点:
https://gist.github.com/alexander-daniel/b36f9be78abbbaa4847e#file-index-js-L33
这样我们就可以看到 Plotly 返回了一个我们可以查看的图表 URL。
https://gist.github.com/alexander-daniel/b36f9be78abbbaa4847e#file-console_output-L5
这应该可以解决第一个问题。
就第二个问题而言,问题似乎有两个方面:
- JSON.parse
库内的调用未包含在 try/catch 中,因此看起来如果流服务器 returns 不是 JSON 的任何内容,这将中断。
我们正在调查流式服务器错误 returns,但我已在此处打开此问题回复:API 库中的 try/catch 块。
github.com/plotly/plotly-nodejs/issues/37
我正在尝试通过向 http://localhost:3000/step
.
POST
请求,以流式传输我的服务器接收到的数据
基于 plotly-nodejs/examples 中的 rest-example.js
,这是我的服务器代码(我模糊了我的用户名、apikey 和令牌):
'use strict';
var express = require('express');
var logger = require('morgan');
var bodyParser = require('body-parser');
var events = require('events');
var eventEmitter = new events.EventEmitter();
var app = express();
var server = require('http').Server(app);
var port = process.env.PORT || 3000;
server.listen(port);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/step', function(req, res) {
var data = req.body.data;
eventEmitter.emit('step', data);
res.end('ok');
});
var plotly = require('plotly')('username', 'apikey');
var token = 'token';
var dataInit = [{x:[], y:[], stream: { token: token, maxpoints: 10 } }];
var layout = {fileopt : "extend", filename : "REST-test"};
plotly.plot(dataInit, layout, function (err, msg) {
if(err) return console.error('step data error', err.stack);
var stream = plotly.stream(token, function() {});
eventEmitter.on('step', function(data) {
console.log('sending to plotly: ' + data + ' steps');
var streamObject = JSON.stringify({ x: getDateString(), y: data });
stream.write(streamObject+'\n');
});
});
function getDateString() {
var d = new Date();
return d.toLocaleString();
};
当我使用 cURL POST
数据时,例如 curl http://localhost:3000/step --data "data=5"
,我可以看到数据到达 plotly.plot
块内的回调,但 plotly 永远不会启动并流式传输数据。
在我之前处理的一些稍微复杂的服务器代码中,我也得到了可能相关也可能不相关的错误,它总是指向 plotly.plot
块的开头。
cb(null, body);
^
SyntaxError: Unexpected end of input
这是完整的错误堆栈:
/home/plotly-testing/node_modules/plotly/index.js:305
cb(null, body);
^
SyntaxError: Unexpected end of input
at Object.parse (native)
at /home/plotly-testing/node_modules/plotly/index.js:72:25
at IncomingMessage.<anonymous> (/home/plotly-testing/node_modules/plotly/index.js:305:9)
at IncomingMessage.emit (events.js:129:20)
at _stream_readable.js:908:16
at process._tickCallback (node.js:355:11)
---------------------------------------------
at IncomingMessage.Readable.on (_stream_readable.js:671:33)
at parseRes (/home/plotly-testing/node_modules/plotly/index.js:304:9)
at ClientRequest.<anonymous> (/home/plotly-testing/node_modules/plotly/index.js:71:9)
at ClientRequest.emit (events.js:107:17)
at HTTPParser.parserOnIncomingClient (_http_client.js:426:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:111:23)
at TLSSocket.socketOnData (_http_client.js:317:20)
---------------------------------------------
at new ClientRequest (_http_client.js:93:10)
at Object.exports.request (http.js:49:10)
at Object.exports.request (https.js:136:15)
at Plotly.plot (/home/plotly-testing/node_modules/plotly/index.js:70:21)
at Object.<anonymous> (/home/plotly-testing/index.js:175:8)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
plotly/index.js
的第 305 行指向以下方法,这似乎表明我的回调之一有问题,但我不确定。
// response parse helper fn
function parseRes (res, cb) {
var body = '';
if ('setEncoding' in res) res.setEncoding('utf-8');
res.on('data', function (data) {
body += data;
if (body.length > 1e10) {
// FLOOD ATTACK OR FAULTY CLIENT, NUKE REQ
res.connection.destroy();
res.writeHead(413, {'Content-Type': 'text/plain'});
res.end('req body too large');
return cb(new Error('body overflow'));
}
});
res.on('end', function () {
cb(null, body);
});
}
所以我修改了代码以在 Plotly.plot
回调中包含一个 console.log
。
在这里查看要点: https://gist.github.com/alexander-daniel/b36f9be78abbbaa4847e#file-index-js-L33
这样我们就可以看到 Plotly 返回了一个我们可以查看的图表 URL。 https://gist.github.com/alexander-daniel/b36f9be78abbbaa4847e#file-console_output-L5
这应该可以解决第一个问题。
就第二个问题而言,问题似乎有两个方面:
- JSON.parse
库内的调用未包含在 try/catch 中,因此看起来如果流服务器 returns 不是 JSON 的任何内容,这将中断。
我们正在调查流式服务器错误 returns,但我已在此处打开此问题回复:API 库中的 try/catch 块。
github.com/plotly/plotly-nodejs/issues/37