* Server-sent event stream *
*********************************************************/
-const events = new EventSource("events");
-
-events.onerror = function(event) {
- if (event.target.readyState === EventSource.CLOSED) {
- add_message("danger", "Connection to server lost.");
- }
-};
+const events = new ReconnectingEventSource("events", {
+ onclose: () => add_message("danger", "Connection to server lost.")
+});
events.addEventListener("game-info", event => {
window.game.set_game_info(JSON.parse(event.data));
* Handling server-sent event stream *
*********************************************************/
-const events = new EventSource("events");
-
-events.onerror = function(event) {
- if (event.target.readyState === EventSource.CLOSED) {
- setTimeout(() => {
- add_message("danger", "Connection to server lost.");
- }, 1000);
- }
-};
+const events = new ReconnectingEventSource("events", {
+ onclose: () => add_message("danger", "Connection to server lost.")
+});
events.addEventListener("game-info", event => {
const info = JSON.parse(event.data);
request.send();
}
-const events = new EventSource(GAME_API("events"));
-
-events.onerror = function(event) {
- if (event.target.readyState === EventSource.CLOSED) {
- add_message("danger", "Connection to server lost.");
- }
-};
+const events = new ReconnectingEventSource(GAME_API("events"), {
+ onclose: () => add_message("danger", "Connection to server lost.")
+});
events.addEventListener("spectators", function(event) {
const spectators_div = document.getElementById("spectators-div");
* Server-sent event stream *
*********************************************************/
-const events = new EventSource("events");
-
-events.onerror = function(event) {
- if (event.target.readyState === EventSource.CLOSED) {
- add_message("danger", "Connection to server lost.");
- }
-};
+const events = new ReconnectingEventSource("events", {
+ onclose: () => add_message("danger", "Connection to server lost.")
+});
events.addEventListener("game-info", event => {
window.game.set_game_info(JSON.parse(event.data));
message_area.insertAdjacentHTML('beforeend', message);
}
+/* An EventSource wrapper that automatically reconnects when the
+ * connection is closed (e.g. server restart). Retries a few times
+ * with a delay before giving up and calling the onclose callback.
+ */
+class ReconnectingEventSource {
+ constructor(url, { max_retries = 5, retry_delay_ms = 2000, onclose } = {}) {
+ this._url = url;
+ this._max_retries = max_retries;
+ this._retry_delay_ms = retry_delay_ms;
+ this._onclose = onclose;
+ this._listeners = [];
+ this._retries = 0;
+ this._closed = false;
+ this._connect();
+ }
+
+ _connect() {
+ this._es = new EventSource(this._url);
+
+ this._es.onopen = () => {
+ this._retries = 0;
+ };
+
+ this._es.onerror = () => {
+ if (this._es.readyState === EventSource.CLOSED) {
+ this._es.close();
+ if (!this._closed && this._retries < this._max_retries) {
+ this._retries++;
+ setTimeout(() => this._connect(), this._retry_delay_ms);
+ } else if (this._onclose) {
+ this._onclose();
+ }
+ }
+ };
+
+ for (const { type, handler } of this._listeners) {
+ this._es.addEventListener(type, handler);
+ }
+ }
+
+ addEventListener(type, handler) {
+ this._listeners.push({ type, handler });
+ this._es.addEventListener(type, handler);
+ }
+
+ close() {
+ this._closed = true;
+ this._es.close();
+ }
+}
+
function lmno_join_loadend(request, game_id) {
if (request.status === 404) {
add_message("danger", game_id + " is not a valid game ID. Try again.");
* Handling server-sent event stream *
*********************************************************/
-const events = new EventSource("events");
-
-events.onerror = function(event) {
- if (event.target.readyState === EventSource.CLOSED) {
- setTimeout(() => {
- add_message("danger", "Connection to server lost.");
- }, 1000);
- }
-};
+const events = new ReconnectingEventSource("events", {
+ onclose: () => add_message("danger", "Connection to server lost.")
+});
events.addEventListener("game-info", event => {
const info = JSON.parse(event.data);
* Handling server-sent event stream *
*********************************************************/
-const events = new EventSource("events");
-
-events.onerror = function(event) {
- if (event.target.readyState === EventSource.CLOSED) {
- add_message("danger", "Connection to server lost.");
- }
-};
+const events = new ReconnectingEventSource("events", {
+ onclose: () => add_message("danger", "Connection to server lost.")
+});
events.addEventListener("game-info", event => {
const info = JSON.parse(event.data);