Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/js/pull/connector/src/transport/ |
Upload File : |
/* eslint-disable @bitrix24/bitrix24-rules/no-native-events-binding */ import { ConnectionType } from '../../../client/src/consts'; import { AbstractConnector } from './base'; import { getDateForLog, isNotEmptyString } from '../../../util/src/util'; import type { ConnectorOptions } from './base'; const LONG_POLLING_TIMEOUT = 60; type LongPollingConnectorOptions = ConnectorOptions & { isBinary: boolean, getPublicationPath: () => string, } export class LongPollingConnector extends AbstractConnector { connectionType = ConnectionType.LongPolling; active = false; requestTimeout = null; failureTimeout = null; requestAborted = false; constructor(config: LongPollingConnectorOptions) { super(config); this.xhr = this.createXhr(); this.isBinary = config.isBinary; } createXhr(): XMLHttpRequest { const result = new XMLHttpRequest(); if (this.isBinary) { result.responseType = 'arraybuffer'; } result.addEventListener('readystatechange', this.onXhrReadyStateChange.bind(this)); return result; } connect() { this.active = true; this.performRequest(); } disconnect(code, reason) { this.active = false; if (this.failureTimeout) { clearTimeout(this.failureTimeout); this.failureTimeout = null; } if (this.requestTimeout) { clearTimeout(this.requestTimeout); this.requestTimeout = null; } if (this.xhr) { this.requestAborted = true; this.xhr.abort(); } this.disconnectCode = code; this.disconnectReason = reason; this.connected = false; } performRequest() { if (!this.active) { return; } if (!this.path) { throw new Error('Long polling connection path is not defined'); } if (this.xhr.readyState !== 0 && this.xhr.readyState !== 4) { return; } clearTimeout(this.failureTimeout); clearTimeout(this.requestTimeout); this.failureTimeout = setTimeout( () => { this.connected = true; }, 5000, ); this.requestTimeout = setTimeout(this.onRequestTimeout.bind(this), LONG_POLLING_TIMEOUT * 1000); this.xhr.open('GET', this.path); this.xhr.send(); } onRequestTimeout() { this.requestAborted = true; this.xhr.abort(); this.performRequest(); } onXhrReadyStateChange() { if (this.xhr.readyState === 4) { if (!this.requestAborted || this.xhr.status === 200) { this.onResponse(this.xhr.response); } this.requestAborted = false; } } /** * Sends some data to the server via http request. */ send(buffer: ArrayBuffer): void { const path = this.parent.getPublicationPath(); if (!path) { console.error(`${getDateForLog()}: Pull: publication path is empty`); return; } const xhr = new XMLHttpRequest(); xhr.open('POST', path); xhr.send(buffer); } onResponse(response) { if (this.failureTimeout) { clearTimeout(this.failureTimeout); this.failureTimeout = 0; } if (this.requestTimeout) { clearTimeout(this.requestTimeout); this.requestTimeout = 0; } if (this.xhr.status === 200) { this.connected = true; if (isNotEmptyString(response) || (response instanceof ArrayBuffer)) { this.callbacks.onMessage(response); } else { this.parent.session.mid = null; } this.performRequest(); } else if (this.xhr.status === 304) { this.connected = true; if (this.xhr.getResponseHeader('Expires') === 'Thu, 01 Jan 1973 11:11:01 GMT') { const lastMessageId = this.xhr.getResponseHeader('Last-Message-Id'); if (isNotEmptyString(lastMessageId)) { this.parent.setLastMessageId(lastMessageId); } } this.performRequest(); } else { this.callbacks.onError('Could not connect to the server'); this.connected = false; } } }