Situation: I am developing an image processing application written in C++ and I have to show the processed frames through a web-interface by reloading a img DOM src every approx. 1 second, i.e. using:
$("#myImage").attr("src", "/myImage.jpg?" + new Date().getTime());
My idea is to use the C++ application as a client, and a server socket opened from the web-interface. Using this approach I could achieve good synchronization for the image update, since I experienced problems while updating the img DOM when the image was incomplete. So
- 1) Every approx. 30 frames, the C++ application connects to the server socket and tell the web-interface that the img can be updated.
- 2) The web-interface updates the DOM img src without any syncronization error.
Based on these requirements, the following is the solution I developed using nginx and nodejs and my little web development experience.
nginx config snippet
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://127.0.0.1:5000;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
HTML code:
<html>
<head>
<meta charset="utf-8">
<meta http-equiv='cache-control' content='no-cache'>
<meta http-equiv='expires' content='0'>
<meta http-equiv='pragma' content='no-cache'>
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery.js"></script>
<title>Frame viewer</title>
<style>
* { padding: 0; margin: 0; vertical-align: top; }
body
{
background-color: #ADACFF;
}
#imageOutputDiv
{
width: 600px;
height: 400px;
border: 1px solid #ccc;
left:50%;
top:50%;
text-align: center;
margin:auto;
}
#footer
{
bottom: 0;
width: 100%;
text-align: center;
position: absolute;
color: black;
}
</style>
<script>
$(function()
{
var socket = io.connect();
socket.on('update', function (data)
{
$("#debugText").text("Updated: " + new Date().getTime().toString());
$("#imageOutput").attr('src', '/image/output.jpg?'+ new Date().getTime().toString());
});
});
</script>
</head>
<body>
<br>
<div id = "bodyTitle">
<h2 style = "text-align:center">Frame viewer</h2>
</div>
<br>
<div id="imageOutputDiv">
<img id="imageOutput"></img>
</div>
<div id="debug">
<h5 id="debugText"></h5>
</div>
<div id="footer">
<h5 id="footerText">test 1.9.1</h5>
</div>
</body>
</html>
NodeJS code
var htmlPath = '/var/www/html/index.html';
var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
var fs = require('fs');
app.listen(5000);
function handler (req, res)
{
fs.readFile(htmlPath, function (err, data)
{
if (err)
{
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(data);
});
}
var net = require('net');
var server = net.createServer(function(extsocket)
{
extsocket.write('# test server\r\n');
extsocket.on('data', function (data)
{
if (data.toString() == 'takeimage')
{
console.log("Received: " + data.toString());
// here I should update DOM debugTxt
io.emit('update', { update: '*' });
}
});
});
server.listen(8080, '0.0.0.0');
The Javascript sockets code executed by nodejs works fine, because I can test the connection on port 8080 with telnet. The problem is that the debugText is updated correctly while the image imageOutput is not visibile, so I suspect I don't have access to it..
If possible, how can I load the image and reload the src attribute correctly ? How do I have to modify my code ?
If you think there are better solutions than using nodejs, I will be happy to read your suggestions.