The following is a demo that uses the fetch API in a browser to subscribe to messages streamed through a GRIP Stream pushed through a sample server that is proxied behind the open-source Pushpin (https://pushpin.org/) server.
To run the demo:
- Clone the js-grip repository, then build the commonjs build.
git clone https://github.com/fanout/js-grip
cd js-grip
npm install
npm run build-commonjs
- Start the server process. This runs on
localhost:3000
.
node demo/server
- Install Pushpin (see https://pushpin.org/docs/install/)
- Make sure Pushpin points to
localhost:3000
.routes
file:
* localhost:3000
- Start Pushpin.
pushpin
This will start a GRIP proxy running on port 7999. A streaming API will be available at http://localhost:7999/stream
.
The API simply holds open a GRIP stream on the channel test
.
- Create an HTML file with the following content. Make adjustments as necessary if you are using a browser that does not support fetch or async/await natively.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pushpin Fetch Demo</title>
</head>
<body>
<h1>Pushpin Fetch Demo</h1>
<div>
<button id="button" type="button">Go</button>
</div>
<div>
<pre id="output" style="color: white; background: black;"></pre>
</div>
<script>
let reader = null;
const button = document.getElementById('button');
button.addEventListener('click', async () => {
if (reader == null) {
// We are not streaming yet.
// We disable the button while we start the fetch
button.disabled = true;
try {
console.log("Fetching.");
const res = await fetch('http://localhost:7999/stream');
reader = res.body.getReader();
} catch(ex) {
console.log("Fetch error.");
reader = null;
} finally {
button.disabled = false;
}
// If we failed at obtaining a reader then we bail out.
if (reader == null) {
return;
}
// We are now streaming.
console.log("Streaming...");
button.innerText = 'Cancel';
// Use the ReadableStream interface to read from the
// response until the stream closes.
let total = 0;
while (true) {
const { done, value } = await reader.read();
if (done) {
// Finished Streaming
break;
}
total += value.length;
console.log(total + " bytes so far...");
document.getElementById('output').textContent +=
new TextDecoder("utf-8").decode(value);
}
console.log("Finished Streaming.");
console.log("Read a total of " + total + " bytes.");
reader = null;
button.innerText = 'Go';
} else {
// If we are already streaming, cancel.
// This will cause the read promise above to resolve with
// a true value for "done", exiting the while loop.
reader.cancel();
reader = null;
}
});
</script>
</body>
</html>
-
Open the HTML file in a web browser. You will see a button labeled
Go
. Click this button. The browser will use fetch to connect to the streaming API athttp://localhost:7999/stream
. -
In another terminal window, run the publish demo file.
cd js-grip
node demo/publish test "Message"
This pushes a message Message
to the channel test
.
- In the web browser window you opened in step 7, you should see the test message.