2016-10-31 3 views
0

Я использую холст узла в проекте; по сути, проект заключается в отображении изображения на экране браузера и в состоянии контролировать положение изображения tge с помощью POST-файлов REST API. Это прекрасно работает, но после POST я хочу обновить браузер автоматически.Javascript узел js браузер обновляется по POST

Я посмотрел на:

  • НПХ пакетах (браузер-обновление и т.д.); но они требуют поставить некоторый код на клиентскую страницу, но у меня нет любой клиентской страницы html.

  • вызов res.redirect; это, кажется, ничего не делает.

  • вызов метода draw() в методе POST: я получаю сообщение об ошибке «write after end».

любая помощь? Опять же, попросите обновить браузер (или его часть) по новым координатам в методе POST.

Код ниже.

Приветствия, Matt

Узел 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; 
+0

Что вызывает POST? У вас не может быть POST, если у вас нет чего-то другого, кроме только картинки на стороне клиента? Что такое клиент? Если клиент является веб-браузером, у вас не может быть POST без какого-либо HTML и/или JS ... – jcaron

+0

вызов сервера (т. Е. Вызов curl) запускает POST с информацией о координатах относительно того, где рисовать изображение , node-canvas позволяет мне отображать pic со стороны сервера .. (см. draw_badge.js ..) – MattLieber

ответ

1

Они, как вы пытаетесь не может работать

  • изображение, которое было доставлено в браузер не может обновляться динамически, просто потому, что это изображение. После того, как сервер поставил и клиент загрузил свою работу.
  • Попытка написать запрос (который может быть одним из сотен), конечно, приведет к «записи после завершения», поскольку конец запроса был, когда изображение сначала загрузилось в вашем браузере.
  • Функция экспресс-res.redirect не может быть вызвана post facto (после запроса), также она будет немедленно перенаправлена, которую вы не ищете.

Простое решение: Обновление с помощью HTTP-заголовка (правильно)

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, будет доставлено следующее изображение потока. Теоретически, ваш браузер будет отображать последний полный кадр, который он получил, таким образом, «обновить» ваше изображение в окне браузера. Это будет решение real, но может быть дорогостоящим с точки зрения времени, затраченного на реализацию.Это потребует некоторых изменений в вашем коде.

нюанс: светлячок только хром поддержка уронили, как я только что узнал:/

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 !'); 
}); 
Смежные вопросы