diff --git a/.gitignore b/.gitignore index 4b753e2..12b2578 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,9 @@ pkged.go # Profiler and test files *.prof *.test + +# Javascript tools +.eslintrc.js +node_modules +package.json +package-lock.json diff --git a/web/static/js/main.js b/web/static/js/main.js new file mode 100644 index 0000000..1356b41 --- /dev/null +++ b/web/static/js/main.js @@ -0,0 +1,18 @@ +import { GSWebSocket } from "./modules/websocket.js"; +import { ViewerCounter } from "./modules/viewerCounter.js"; + +// Create WebSocket +const s = new GSWebSocket(); +s.open(() => { + // FIXME open callback +}, () => { + // FIXME close callback +}); + +// Create viewer counter +const streamName = "demo"; // FIXME +const viewerCounter = new ViewerCounter( + document.getElementById("connected-people"), + streamName, +); +viewerCounter.regularUpdate(1000); // FIXME diff --git a/web/static/js/modules/viewerCounter.js b/web/static/js/modules/viewerCounter.js new file mode 100644 index 0000000..9c26d29 --- /dev/null +++ b/web/static/js/modules/viewerCounter.js @@ -0,0 +1,29 @@ +/** + * ViewerCounter show the number of active viewers + */ +export class ViewerCounter { + /** + * @param {HTMLElement} element + * @param {String} streamName + */ + constructor(element, streamName) { + this.element = element; + this.url = "/_stats/" + streamName; + } + + /** + * Regulary update counter + * + * @param {Number} updatePeriod + */ + regularUpdate(updatePeriod) { + setInterval(this._refreshViewersCounter, updatePeriod); + } + + _refreshViewersCounter() { + fetch(this.url) + .then(response => response.json()) + .then((data) => this.element.innerText = data.ConnectedViewers) + .catch(console.log); + } +} diff --git a/web/static/js/modules/websocket.js b/web/static/js/modules/websocket.js new file mode 100644 index 0000000..f6a31c7 --- /dev/null +++ b/web/static/js/modules/websocket.js @@ -0,0 +1,55 @@ +/** + * GsWebSocket to do Ghostream signalling + */ +export class GsWebSocket { + constructor() { + const protocol = (window.location.protocol === "https:") ? "wss://" : "ws://"; + this.url = protocol + window.location.host + "/_ws/"; + } + + _open() { + this.socket = new WebSocket(this.url); + } + + /** + * Open websocket. + * + * @param {Function} openCallback Function called when connection is established. + * @param {Function} closeCallback Function called when connection is lost. + */ + open(openCallback, closeCallback) { + this._open(); + this.socket.addEventListener("open", (event) => { + console.log("WebSocket opened"); + openCallback(event); + }); + this.socket.addEventListener("close", (event) => { + console.log("WebSocket closed, retrying connection in 1s..."); + setTimeout(this._open, 1000); + closeCallback(event); + }); + this.socket.addEventListener("error", (event) => { + console.log("WebSocket errored, retrying connection in 1s..."); + setTimeout(this._open, 1000); + closeCallback(event); + }); + } + + /** + * Exchange WebRTC session description with server. + * + * @param {string} data JSON formated data + * @param {Function} receiveCallback Function called when data is received + */ + exchangeDescription(data, receiveCallback) { + if (this.socket.readyState !== 1) { + console.log("WebSocket not ready to send data"); + return; + } + this.socket.send(data); + this.socket.addEventListener("message", (event) => { + console.log("Message from server ", event.data); + receiveCallback(event); + }); + } +}