Skip to content

Instantly share code, notes, and snippets.

@cjihrig
Last active June 24, 2017 03:56
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cjihrig/e6cee8cac0d6a44beb3b to your computer and use it in GitHub Desktop.
Save cjihrig/e6cee8cac0d6a44beb3b to your computer and use it in GitHub Desktop.
Proxying Server Sent Events Using Hapi
  1. Place server.js and sse.html in the same directory
  2. npm install hapi nipple
  3. node server.js
  4. In browser that supports Server Sent Events, navigate to http://localhost:3000/sse.html
  • Navigating to this page triggers a connection to /stream.
  • /stream connects to /events and proxies the data back to the client.
  • /events provides the actual Server Sent Events stream.
"use strict";
var Stream = require("stream");
var Hapi = require("hapi");
var Nipple = require("nipple");
var server = new Hapi.Server(3000);
server.route({
method: "GET",
path: "/sse.html",
handler: {
file: "./sse.html"
}
});
server.route({
method: "GET",
path: "/events",
handler: function(request, reply) {
var channel = new Stream.PassThrough();
var data = 0;
var interval = setInterval(function() {
channel.write("data: " + data + "\n\n");
console.log("Sending data: " + data);
data++;
}, 1000);
var response = reply(channel);
response.code(200)
.type("text/event-stream")
.header("Connection", "keep-alive")
.header("Cache-Control", "no-cache")
.header("Content-Encoding", "identity");
request.once("disconnect", function() {
clearInterval(interval);
});
}
});
server.route({
method: "GET",
path: "/stream",
handler: function(request, reply) {
Nipple.request("GET", server.info.uri + "/events", {
headers: {
accept: "text/event-stream"
}
}, reply);
}
});
server.start(function() {
console.log("Server started at " + server.info.uri);
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>Server-Sent Events Demo</title>
<meta charset="UTF-8" />
<script>
window.addEventListener("load", function() {
var button = document.getElementById("connect");
var status = document.getElementById("status");
var output = document.getElementById("output");
var connectTime = document.getElementById("connecttime");
var source;
function connect() {
source = new EventSource("stream");
source.addEventListener("message", function(event) {
output.textContent = event.data;
}, false);
source.addEventListener("connecttime", function(event) {
connectTime.textContent = "Connection was last established at: " + event.data;
}, false);
source.addEventListener("open", function(event) {
button.value = "Disconnect";
button.onclick = function(event) {
source.close();
button.value = "Connect";
button.onclick = connect;
status.textContent = "Connection closed!";
};
status.textContent = "Connection open!";
}, false);
source.addEventListener("error", function(event) {
if (event.target.readyState === EventSource.CLOSED) {
source.close();
status.textContent = "Connection closed!";
} else if (event.target.readyState === EventSource.CONNECTING) {
status.textContent = "Connection closed. Attempting to reconnect!";
} else {
status.textContent = "Connection closed. Unknown error!";
}
}, false);
}
if (!!window.EventSource) {
connect();
} else {
button.style.display = "none";
status.textContent = "Sorry, your browser doesn't support server-sent events";
}
}, false);
</script>
</head>
<body>
<input type="button" id="connect" value="Connect" /><br />
<span id="status">Connection closed!</span><br />
<span id="connecttime"></span><br />
<span id="output"></span>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment