Javascript节点js浏览器在POST时刷新

时间:2016-10-31 22:56:31

标签: node.js canvas

我在项目中使用节点画布;本质上该项目是关于在浏览器屏幕上显示图像,并能够通过REST API POST控制tge图像的位置。这很好,但在POST时我想自动刷新浏览器。

我看过:

  • npm包(浏览器刷新等);但他们需要在客户端页面中放置一些代码,但我没有任何html客户端页面。

  • 调用res.redirect;这似乎无能为力。

  • 在POST方法中调用我的draw()方法:我得到一个关于'写完后'的错误。

任何帮助?同样,问题是在POST方法中刷新浏览器(或其中的一部分)。

以下代码。

干杯, 马特

节点server.js:

//Lets require/import the HTTP module
var http = require('http');
var express = require('express');
var app = express();
var bodyParser = require('body-parser')
var fs = require('fs')
var path = require('path')

var draw = require('./draw_badge');

var robot1;
var robot1_xcoord = 30;    
var robot1_ycoord = 100;    

var robot2;
var robot2_xcoord = 50;
var robot2_ycoord = 30;    

/** bodyParser.urlencoded(options)
 * Parses the text as URL encoded data (which is how browsers tend to send form data from regular forms set to POST)
 * and exposes the resulting object (containing the keys and values) on req.body
 */
app.use(bodyParser.urlencoded({
    extended: true
}));
/**bodyParser.json(options)
 * Parses the text as JSON and exposes the resulting object on req.body.
 */
app.use(bodyParser.json());

/** -------- Start -----
 *
 */



  {
    app.get('/', function (req, res) {

   console.log("Xcoord: " + robot1_xcoord);
  res.setHeader('Content-Type', 'image/png');
  // redraw everything
  draw(robot1_xcoord,robot1_ycoord, robot2_xcoord,robot2_ycoord).pngStream().pipe(res);

});


 // Getting a POST
app.post('/', function (req, res) {
  console.log(req.body.id);
if (req.body.id=="1")
{
  console.log("robot1 change");
  robot1_xcoord = req.body.xcoordinate;
  robot1_ycoord = req.body.ycoordinate;
}
else
 if (req.body.id=="2")
{
  console.log("robot2 change");

  robot2_xcoord = req.body.xcoordinate;
  robot2_ycoord = req.body.ycoordinate;
}
 // draw(robot1_xcoord,robot1_ycoord, robot2_xcoord,robot2_ycoord).pngStream().pipe(res);
//res.redirect('localhost:5000');
res.send('Got a POST request' );

// try
//res.redirect(req.get('referer'));
/*
 return http.get({
        host: 'localhost',
        path: '/'
    }, function(response) {
        // Continuously update stream with data
        var body = '';
        response.on('data', function(d) {
            body += d;
        });
        response.on('end', function() {

            // Data reception is done, do whatever with it!
            var parsed = JSON.parse(body);

        });
    });
*/

});
 // Main app - Listen
app.listen(process.env.PORT || 5000, function () {
  console.log('Example app listening !');
});

draw_badge.js:

var Canvas = require('canvas')
var fs = require('fs')


function draw_badge(x,y) {


   var x, y, i

  ctx.clearRect(0, 0, 120, 120)

  ctx.save()

  ctx.translate(160, 160) 
  ctx.beginPath()
  ctx.lineWidth = 14
  ctx.strokeStyle = '#325FA2'
  ctx.fillStyle = '#eeeeee'

  ctx.arc(x, y, 42, 0, Math.PI * 2, true)
  ctx.stroke()
  ctx.fill()


 return canvas;
}


function draw_robot(x,y) {

var Image = Canvas.Image
var canvas = new Canvas(600, 600)
var ctx = canvas.getContext('2d')


var img = new Image()
img.src = canvas.toBuffer()
ctx.drawImage(img, 0, 0, 50, 50)
ctx.drawImage(img, 50, 0, 50, 50)
ctx.drawImage(img, 100, 0, 50, 50)

img.src = fs.readFileSync('./kuka.png')
ctx.drawImage(img, 100, 0, img.width , img.height )

//img = new Image()
img.src = fs.readFileSync('./robot.jpeg')
ctx.drawImage(img, x, y, img.width / 2, img.height / 2)
// new


canvas.createPNGStream().pipe(fs.createWriteStream('./image-robot.png'))
return canvas

}

function draw(x1,y1,x2,y2)
{
  Image = Canvas.Image,
      canvas = new Canvas(600, 600),
      ctx = canvas.getContext('2d');
  canvas = draw_robot(x1,y1);
  canvas = draw_badge(x2,y2);
  return canvas;
}

module.exports = draw;

1 个答案:

答案 0 :(得分:1)

他们尝试的方式无法正常工作

  • 传送到浏览器的图像无法动态刷新,只是因为它是图像。一旦服务器交付并且客户端加载了他们的工作就完成了。
  • 尝试写入请求(可能是数百个中的一个)当然会导致“一个接一个写”,因为请求的结束是在浏览器中首次加载图像时。
  • 快递res.redirect函数也不能在事后调用(在请求之后),也会立即重定向,这是你不想要的。

简单解决方案:通过HTTP-Header刷新(正确)

app.get('/', function (req, res) {
   console.log("Xcoord: " + robot1_xcoord);
   res.setHeader('Content-Type', 'image/png');
   // refresh every second
   res.setHeader('Refresh','1');
   // redraw everything
   draw(robot1_xcoord,robot1_ycoord,robot2_xcoord,robot2_ycoord).pngStream().pipe(res);

});

真正的解决方案:流媒体图片

您可以提供实际的图像流。我们的想法是,您对图片的请求永远不会被关闭,当您通过REST-API更改图片时,流的下一张图片将被传递。理论上,您的浏览器将显示它获得的最后一个完整帧,从而在浏览器窗口中“更新”您的图像。这将是真正的解决方案,但就实施浪费的时间而言可能是昂贵的。这将需要在您的代码中进行一些重新安排。

警告:仅限Firefox,我刚刚学会了Chrome支持:/

<强> server.js

//Lets require/import the HTTP module
var http = require('http');
var express = require('express');
var app = express();
var bodyParser = require('body-parser')
var fs = require('fs')
var path = require('path')

var draw = require('./draw_badge');

var robot1;
var robot1_xcoord = 30;
var robot1_ycoord = 100;

var robot2;
var robot2_xcoord = 50;
var robot2_ycoord = 30;

// An array to hold a list of active clients
var clients = [];

// draw an initial version of your buffer
var imageData = draw(robot1_xcoord, robot1_ycoord, robot2_xcoord, robot2_ycoord).toBuffer(undefined, 3, canvas.PNG_FILTER_NONE);
// get the size in bytes as well, we'll need it
var length = imageData.byteLength;

/** bodyParser.urlencoded(options)
 * Parses the text as URL encoded data (which is how browsers tend to send form data from regular forms set to POST)
 * and exposes the resulting object (containing the keys and values) on req.body
 */
app.use(bodyParser.urlencoded({
  extended: true
}));
/**bodyParser.json(options)
 * Parses the text as JSON and exposes the resulting object on req.body.
 */
app.use(bodyParser.json());

/** -------- Start -----
 *
 */

app.get('/', function(req, res) {
  // prepare header so that the browser will wait for arbitray updates
  res.writeHead(200, {
    'Content-Type': 'multipart/x-mixed-replace; boundary=--NEW_IMAGE_HERE',
    'Cache-Control': 'no-cache',
    'Connection': 'close',
    'Pragma': 'no-cache'
  });
  var on_update = function(imageData, length) {
      try {
        console.log("Updating client.. bytes:", length)
        res.write("--NEW_IMAGE_HERE\r\n");
        res.write("Content-Type: image/png\r\n");
        res.write("Content-Length: " + length + "\r\n\r\n");
        res.write(imageData);
      } catch (e) { // in case of an error remove from the clients array
        console.log("Error: ", e);
        clients.splice(clients.indexOf(on_update), 1);
      }
    }
    // remove on disconnect
  res.on('close', function() {
    console.log("Disconnected");
    clients.splice(clients.indexOf(on_update), 1);
  });
  // send the client our last cached version of the image
  on_update(imageData, length);
  // add our update function to the array of clients
  clients.push(on_update);
});

// Getting a POST
app.post('/', function(req, res) {
  console.log(req.body.id);
  if (req.body.id == "1") {
    console.log("robot1 change");
    robot1_xcoord = req.body.xcoordinate;
    robot1_ycoord = req.body.ycoordinate;
  } else
  if (req.body.id == "2") {
    console.log("robot2 change");
    robot2_xcoord = req.body.xcoordinate;
    robot2_ycoord = req.body.ycoordinate;
  }
  res.send('Got a POST request');
  // redraw everything into the buffer
  imageData = draw(robot1_xcoord, robot1_ycoord, robot2_xcoord, robot2_ycoord).toBuffer(undefined, 3, canvas.PNG_FILTER_NONE);
  length = imageData.byteLength;
  // notify active clients
  for (on_update of clients) {
    on_update(imageData, length);
  }
});
// Main app - Listen
app.listen(process.env.PORT || 5000, function() {
  console.log('Example app listening !');
});