2016-10-31 3 views
0

Ich verwende Knoten Leinwand in einem Projekt; Im Wesentlichen geht es bei dem Projekt darum, ein Bild auf dem Browser-Bildschirm anzuzeigen und die Position des Bildes über REST-API-POSTs zu steuern. Das funktioniert gut, aber bei einem POST möchte ich den Browser automatisch aktualisieren.Javascript Knoten js Browser aktualisieren nach POST

Ich habe sah:

  • npm Pakete (Browser-Refresh, usw.); aber sie benötigen etwas Code in die Client-Seite, aber ich habe keine HTML-Client-Seite.

  • Aufruf res.redirect; das scheint nichts zu tun.

  • Aufruf meiner draw() - Methode in der POST-Methode: Ich bekomme einen Fehler über 'nach dem Ende schreiben'.

Hilfe? Auch hier besteht die Frage darin, den Browser (oder einen Teil davon) nach neuen Koordinaten in der POST-Methode zu aktualisieren.

Code unten.

Prost, Matt

Node 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 !'); 
}); 

und

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

Was die POST auslöst? Sie können keinen POST haben, wenn Sie auf der Clientseite nicht nur ein Bild haben? Was ist der Kunde? Wenn der Client ein Webbrowser ist, können Sie keinen POST ohne HTML und/oder JS ... – jcaron

+0

ein Aufruf an den Server (dh Curl-Aufruf) löst den POST mit Koordinateninformationen, wo das Bild zu zeichnen . Mit node-canvas kann ich ein Bild von der Serverseite rendern. (siehe draw_badge.js ..) – MattLieber

Antwort

1

Sie Art und Weise versuchen Sie nicht

  • Das Bild, das an den Browser geliefert wurde, kann nicht dynamisch aktualisiert arbeiten können, nur weil es ein Bild ist. Sobald der Server geliefert hat und der Client geladen ist, ist seine Arbeit erledigt.
  • Der Versuch, auf die Anfrage zu schreiben (was einer von Hunderten sein kann) führt natürlich zu einem "Schreiben nach Ende", weil das Ende der Anfrage war, als das Bild zuerst in Ihrem Browser geladen wurde.
  • die Express Res.Redirect-Funktion kann nicht post facto (nach der Anfrage) entweder aufgerufen werden, auch würde es sofort umleiten, die Sie nicht suchen.

Einfache Lösung: Aktualisieren über HTTP-Header (korrekt)

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); 

}); 

Echt Lösung: Streaming-Bild

Sie könnten einen tatsächlichen Bild-Strom liefern. Die Idee, dass Ihre Anfrage an das Bild niemals geschlossen werden würde, und wenn Sie das Bild über Ihre REST-API ändern, würde das nächste Bild des Streams geliefert werden. Theoretisch würde Ihr Browser den letzten vollständigen Rahmen anzeigen, den er erhalten hat, und somit Ihr Bild im Browserfenster "aktualisieren". Dies wäre die echte Lösung hier, könnte aber teuer in Bezug auf die Zeit verschwendet für die Implementierung sein.Dies würde einige Änderungen in Ihrem Code erfordern.

caveat: firefox nur, Chrom Unterstützung fallen gelassen wurde, wie ich gerade gelernt:/

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 !'); 
}); 
Verwandte Themen