examples: add a WebSocket example (#218)
There is nothing really to do in order to support events over websockets. Since a `CloudEvent` can easily be represented in full with JSON, it can be sent over a websocket as `event.toString()`. This example illustrates sending a `CloudEvent` over websocket from a browser or CLI. Fixes: https://github.com/cloudevents/sdk-javascript/issues/156 Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
parent
8b2725b10a
commit
99bb88be00
|
@ -0,0 +1,45 @@
|
|||
# WebSocket Example
|
||||
|
||||
This example shows how simple it is to use CloudEvents over a websocket
|
||||
connection. The code here shows backend communication from two server
|
||||
side processes, and also between a browser and a server process.
|
||||
|
||||
## Running the Example
|
||||
|
||||
This simple project consists of a server and a client. The server receives
|
||||
`CloudEvents` from the client over a local websocket connection.
|
||||
|
||||
|
||||
To get started, first install dependencies.
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
### Server
|
||||
The server opens a websocket and waits for incoming connections. It expects that any
|
||||
messages it receives will be a CloudEvent. When received, it reads the data field,
|
||||
expecting a zip code. It then fetches the current weather for that zip code and
|
||||
responds with a CloudEvent containing the body of the Weather API response as the
|
||||
event data.
|
||||
|
||||
You will need to change one line in the `server.js` file and provide your Open
|
||||
Weather API key.
|
||||
|
||||
To start the server, run `node server.js`.
|
||||
|
||||
### Client
|
||||
Upon start, the client prompts a user for a zip code, then sends a CloudEvent over
|
||||
a websocket to the server with the provided zip code as the event data. The server
|
||||
fetches the current weather for that zip code and returns it as a CloudEvent. The
|
||||
client extracts the data and prints the current weather to the console.
|
||||
|
||||
To start the client, run `node client.js`
|
||||
|
||||
### Browser
|
||||
Open the [`index.html`]('./index.html') file in your browser and provide a zip
|
||||
code in the provided form field. The browser will send the zip code in the data
|
||||
field of a CloudEvent over a websocket. When it receives a response from the server
|
||||
it prints the weather, or an error message, to the screen.
|
||||
|
||||
To terminate the client or server, type CTL-C.
|
|
@ -0,0 +1,46 @@
|
|||
/* eslint-disable no-console */
|
||||
const readline = require("readline");
|
||||
const WebSocket = require("ws");
|
||||
const ws = new WebSocket("ws://localhost:8080");
|
||||
|
||||
const { CloudEvent } = require("cloudevents-sdk");
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
|
||||
rl.on("close", (_) => console.log("\n\nConnection closed! Press CTL-C to exit."));
|
||||
|
||||
ws.on("message", function incoming(message) {
|
||||
const event = new CloudEvent(JSON.parse(message));
|
||||
if (event.type === "weather.error") {
|
||||
console.error(`Error: ${event.data}`);
|
||||
} else {
|
||||
print(event.data);
|
||||
}
|
||||
ask();
|
||||
});
|
||||
|
||||
function ask() {
|
||||
rl.question("Would you like to see the current weather? Provide a zip code: ", function (zip) {
|
||||
console.log("Fetching weather data from server...");
|
||||
ws.send(new CloudEvent({
|
||||
type: "weather.query",
|
||||
source: "/weather.client",
|
||||
data: zip
|
||||
}).toString());
|
||||
});
|
||||
}
|
||||
|
||||
function print(data) {
|
||||
data = JSON.parse(data);
|
||||
console.log(`
|
||||
Current weather for ${data.name}: ${data.weather[0].main}
|
||||
------------------------------------------
|
||||
With ${data.weather[0].description}, the temperature is ${Math.round(data.main.temp)}F
|
||||
and the wind is blowing at ${Math.round(data.wind.speed)}mph.
|
||||
`);
|
||||
}
|
||||
|
||||
ask();
|
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CloudEvent Example</title>
|
||||
<script src="../../bundles/cloudevents-sdk.js"></script>
|
||||
<script>
|
||||
const CloudEvent = window['cloudevents-sdk'].CloudEvent;
|
||||
const socket = new WebSocket("ws://localhost:8080");
|
||||
|
||||
function print(weather) {
|
||||
const data = JSON.parse(weather);
|
||||
const summary = `
|
||||
<h2>Current weather for ${data.name}: ${data.weather[0].main}</h2>
|
||||
<hr/>
|
||||
<p>
|
||||
With ${data.weather[0].description}, the temperature is ${Math.round(data.main.temp)}F
|
||||
and the wind is blowing at ${Math.round(data.wind.speed)}mph.
|
||||
</p>`;
|
||||
console.log(summary);
|
||||
const node = document.getElementById("summary");
|
||||
node.innerHTML = summary;
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
socket.onmessage = function(message) {
|
||||
console.log(message.data)
|
||||
const event = new CloudEvent(JSON.parse(message.data));
|
||||
if (event.type === "weather.error") {
|
||||
console.error(`Error: ${event.data}`);
|
||||
alert(`Error: ${event.data}`);
|
||||
} else {
|
||||
print(event.data);
|
||||
}
|
||||
}
|
||||
|
||||
const input = document.getElementById("zip");
|
||||
input.addEventListener("keyup", function(event) {
|
||||
if (event.keyCode === 13) {
|
||||
event.preventDefault();
|
||||
socket.send(new CloudEvent({
|
||||
type: "weather.query",
|
||||
source: "/weather.client",
|
||||
data: input.value
|
||||
}).toString());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body style="font-size: larger; margin: 1em;" onload="initialize()">
|
||||
<h1>Weather By Zip Code</h1>
|
||||
<p>Please provide a zip code
|
||||
<input type="text" id="zip"/>
|
||||
</p>
|
||||
<p style="font-family: Arial, Helvetica, sans-serif;" id="summary">
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "websocket-cloudevents",
|
||||
"version": "0.0.1",
|
||||
"description": "An example application that sends and receives CloudEvents over a websocket",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js"
|
||||
},
|
||||
"keywords": [
|
||||
"cloudevents",
|
||||
"example",
|
||||
"websocket"
|
||||
],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cloudevents-sdk": "^2.0.2",
|
||||
"got": "^11.3.0",
|
||||
"ws": "^7.3.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/* eslint-disable no-console */
|
||||
const got = require("got");
|
||||
|
||||
const { CloudEvent } = require("cloudevents-sdk");
|
||||
const WebSocket = require("ws");
|
||||
const wss = new WebSocket.Server({ port: 8080 });
|
||||
|
||||
const api = "https://api.openweathermap.org/data/2.5/weather";
|
||||
const key = "REPLACE WITH API KEY";
|
||||
|
||||
console.log("WebSocket server started. Waiting for events.");
|
||||
|
||||
wss.on("connection", function connection(ws) {
|
||||
console.log("Connection received");
|
||||
ws.on("message", function incoming(message) {
|
||||
const event = new CloudEvent(JSON.parse(message));
|
||||
console.log(`Message received: ${event.toString()}`);
|
||||
fetch(event.data)
|
||||
.then((weather) => {
|
||||
ws.send(new CloudEvent({
|
||||
dataContentType: "application/json",
|
||||
type: "current.weather",
|
||||
source: "/weather.server",
|
||||
data: weather
|
||||
}).toString());
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
ws.send(new CloudEvent({
|
||||
type: "weather.error",
|
||||
source: "/weather.server",
|
||||
data: err.toString()
|
||||
}).toString());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function fetch(zip) {
|
||||
const query = `${api}?zip=${zip}&appid=${key}&units=imperial`;
|
||||
return new Promise((resolve, reject) => {
|
||||
got(query)
|
||||
.then((response) => resolve(response.body))
|
||||
.catch((err) => reject(err.message));
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue