Ver código fonte

client automatically reloads when the server restarts, and fixed issues with caching

master
mort 8 anos atrás
pai
commit
d8324c4031
3 arquivos alterados com 160 adições e 30 exclusões
  1. 32
    4
      index.html
  2. 20
    0
      npm-debug.log
  3. 108
    26
      server.js

+ 32
- 4
index.html Ver arquivo

} }


// Change slides with a transition // Change slides with a transition
function update() {
function update(name) {
overlay().innerHTML = ""; overlay().innerHTML = "";
overlay().className = "_content"; overlay().className = "_content";
swap(main(), overlay()); swap(main(), overlay());
.then(response => response.text()) .then(response => response.text())
.then(text => { .then(text => {
setTimeout(() => { setTimeout(() => {
history.replaceState({}, "", "/"+name+"/");
main().innerHTML = text; main().innerHTML = text;
overlay().className = "_content hidden"; overlay().className = "_content hidden";
}, 1000); }, 1000);
}) })
.catch(err => console.error(err)); .catch(err => console.error(err));
}

function reload() {
var i = setInterval(() => {
fetch("/")
.then(() => {
history.replaceState({}, "", "/");
location.reload();
})
.catch(() => {});
}, 1000);
}


function await() {
// Wait for the next slide change, then update again // Wait for the next slide change, then update again
fetch("/await") fetch("/await")
.then(response => update())
.catch(err => { console.error(err); update(); });
.then(response => response.json())
.then(obj => {
if (obj.evt === "next") {
update(obj.args.name);
} else if (obj.evt === "reload") {
return reload();
} else {
console.log("Unknown event: "+obj.evt);
}
await();
})
.catch(err => { console.error(err); await(); });
} }


update();
await();

fetch("/init")
.then(response => response.text())
.then(name => update(name));
</script> </script>
</body> </body>
</html> </html>

+ 20
- 0
npm-debug.log Ver arquivo

0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'start' ]
2 info using npm@3.8.3
3 info using node@v5.10.1
4 verbose stack Error: ENOENT: no such file or directory, open '/var/www/mrow.me/sonen/package.json'
4 verbose stack at Error (native)
5 verbose cwd /var/www/mrow.me/sonen
6 error Linux 3.16.0-4-amd64
7 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
8 error node v5.10.1
9 error npm v3.8.3
10 error path /var/www/mrow.me/sonen/package.json
11 error code ENOENT
12 error errno -2
13 error syscall open
14 error enoent ENOENT: no such file or directory, open '/var/www/mrow.me/sonen/package.json'
15 error enoent ENOENT: no such file or directory, open '/var/www/mrow.me/sonen/package.json'
15 error enoent This is most likely not a problem with npm itself
15 error enoent and is related to npm not being able to find a file.
16 verbose exit [ -2, true ]

+ 108
- 26
server.js Ver arquivo

res.end(err.toString()); res.end(err.toString());
} }


function mimetype(path) {
var ext = pathlib.extname(path)
.substring(1)
.toLowerCase();

switch (ext) {

case "html":
case "xml":
return "text/"+ext;

case "png":
case "jpg":
case "jpeg":
case "gif":
return "image/"+ext;

case "svg":
return "image/svg+xml";

case "mov":
case "mp4":
case "ogv":
case "webm":
return "video/"+ext;

case "mp3":
case "ogg":
case "flac":
case "m4a":
return "audio/"+ext;

default:
return "application/octet-stream";
}
}

function sendfile(res, path) {
res.writeHead(200, {
"content-type": mimetype(path)
});

fs.createReadStream(path)
.on("error", err => error(res, err))
.pipe(res);
}

// The individual slide // The individual slide
function Slide(dir) { function Slide(dir) {
var self = {}; var self = {};


self.dir = dir; self.dir = dir;
self.name = pathlib.parse(dir).name;


function serve(parts, res) {
if (parts.pathname === "/slide") {
fs.createReadStream(pathlib.join(dir, "index.html"))
.on("error", err => error(res, err))
.pipe(res);
} else {
fs.createReadStream(pathlib.join(dir, parts.pathname))
.on("error", err => error(res, err))
.pipe(res);
}
self.serveSlide = function(parts, res) {
sendfile(res, pathlib.join(dir, "index.html"));
} }


self.serve = function(parts, res) {
try {
serve(parts, res);
} catch (err) {
if (err.code && err.code === "ENOENT")
res.writeHead(404);
self.serveFiles = function(parts, res) {


error(res, err);
// Redirect to / if /{name} is requested
if (parts.pathname.replace(/\//g, "") === self.name) {
res.writeHead(302, { location: "/" });
return res.end();
} }

var name = parts.pathname.substring(1).replace(self.name, "");
sendfile(res, pathlib.join(dir, name));
} }


return self; return self;


var currentSlide = null; var currentSlide = null;
var awaiters = []; var awaiters = [];
var slides = [];

self.sendEvent = function(evt, args) {
awaiters.forEach(res => res.end(JSON.stringify({
evt: evt,
args: args
})));
}


self.serve = function(req, res) { self.serve = function(req, res) {
var parts = urllib.parse(req.url); var parts = urllib.parse(req.url);
if (parts.pathname === "/") { if (parts.pathname === "/") {
res.end(index); res.end(index);


// /init: send initial information about current slide
} else if (parts.pathname === "/init") {
res.end(currentSlide ? currentSlide.name : "");

// /await: long polling, request won't end before a new slide comes // /await: long polling, request won't end before a new slide comes
} else if (parts.pathname === "/await") { } else if (parts.pathname === "/await") {
awaiters.push(res); awaiters.push(res);


// There's a current slide: leave serving files up to the slide
} else if (currentSlide) {
currentSlide.serve(parts, res);
// /slide: serve the current slide's html
} else if (parts.pathname === "/slide" && currentSlide) {
currentSlide.serveSlide(parts, res);


// There's no current slide show
// Serve other files
} else { } else {
res.end("No current slideshow.");
var served = false;

for (var slide of slides) {

// If client requests /{slide-name}/*
if (slide.name === parts.pathname.substr(1, slide.name.length)) {
slide.serveFiles(parts, res);
served = true;
break;
}
}

if (!served) {
res.writeHead(404);
res.end("404");
}
} }
} }


// This function starts the slideshow and goes through the slides // This function starts the slideshow and goes through the slides
// one by one. When done, it starts again by calling this function again. // one by one. When done, it starts again by calling this function again.
function init() { function init() {
var slides = fs.readdirSync(dir)
slides = fs.readdirSync(dir)
.sort() .sort()
.map(file => Slide(pathlib.join(dir, file))); .map(file => Slide(pathlib.join(dir, file)));


} }


// End all awaiting connections to notify slide change // End all awaiting connections to notify slide change
awaiters.forEach(res => res.end());
self.sendEvent("next", { name: currentSlide.name });
}, changeInterval); }, changeInterval);
} }
init(); init();


var slideshow = Slideshow(conf.slides, conf.interval); var slideshow = Slideshow(conf.slides, conf.interval);


http.createServer((req, res) => {
function onexit() {
slideshow.sendEvent("reload");
process.exit();
}
process.on("exit", onexit);
process.on("SIGINT", onexit);
process.on("SIGTERM", onexit);

var server = http.createServer((req, res) => {
slideshow.serve(req, res); slideshow.serve(req, res);
}).listen(conf.port);
});
server.on("error", err => {
console.error(err.toString());
system.exit(1);
});
server.listen(conf.port);
console.log("Server running on port "+conf.port+".");

Carregando…
Cancelar
Salvar