const message_area = document.getElementById('message-area');
message_area.insertAdjacentHTML('beforeend', message);
}
+
+ 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();
+ }
+ }
</script>
{% block head %}
{% endblock %}