Detect available transport
This commit is contained in:
parent
ac8e36a20b
commit
5451eefe80
@ -18,7 +18,7 @@ const Modes = {
|
|||||||
ssl: true, // location.search.indexOf('ssl=1') > 0 || location.protocol === 'https:' && location.search.indexOf('ssl=0') === -1,
|
ssl: true, // location.search.indexOf('ssl=1') > 0 || location.protocol === 'https:' && location.search.indexOf('ssl=0') === -1,
|
||||||
multipleConnections: true,
|
multipleConnections: true,
|
||||||
asServiceWorker: false,
|
asServiceWorker: false,
|
||||||
transport: 'https' as TransportType
|
transport: 'websocket' as TransportType
|
||||||
};
|
};
|
||||||
|
|
||||||
/// #if MTPROTO_HAS_HTTP
|
/// #if MTPROTO_HAS_HTTP
|
||||||
|
@ -36,6 +36,10 @@ import Modes from '../../config/modes';
|
|||||||
import rootScope from '../rootScope';
|
import rootScope from '../rootScope';
|
||||||
/// #endif
|
/// #endif
|
||||||
|
|
||||||
|
/// #if MTPROTO_AUTO
|
||||||
|
import transportController from './transports/controller';
|
||||||
|
/// #endif
|
||||||
|
|
||||||
/* var networker = apiManager.cachedNetworkers.websocket.upload[2];
|
/* var networker = apiManager.cachedNetworkers.websocket.upload[2];
|
||||||
networker.wrapMtpMessage({
|
networker.wrapMtpMessage({
|
||||||
_: 'msgs_state_req',
|
_: 'msgs_state_req',
|
||||||
@ -106,6 +110,12 @@ export class ApiManager {
|
|||||||
this.afterMessageTempIds = {};
|
this.afterMessageTempIds = {};
|
||||||
|
|
||||||
this.transportType = Modes.transport;
|
this.transportType = Modes.transport;
|
||||||
|
|
||||||
|
/// #if MTPROTO_AUTO
|
||||||
|
transportController.addEventListener('transport', (transportType) => {
|
||||||
|
this.changeTransportType(transportType);
|
||||||
|
});
|
||||||
|
/// #endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//private lol = false;
|
//private lol = false;
|
||||||
@ -168,6 +178,12 @@ export class ApiManager {
|
|||||||
|
|
||||||
public changeTransportType(transportType: TransportType) {
|
public changeTransportType(transportType: TransportType) {
|
||||||
const oldTransportType = this.transportType;
|
const oldTransportType = this.transportType;
|
||||||
|
if(oldTransportType === transportType) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log('changing transport from', oldTransportType, 'to', transportType);
|
||||||
|
|
||||||
const oldObject = this.cachedNetworkers[oldTransportType];
|
const oldObject = this.cachedNetworkers[oldTransportType];
|
||||||
const newObject = this.cachedNetworkers[transportType];
|
const newObject = this.cachedNetworkers[transportType];
|
||||||
this.cachedNetworkers[transportType] = oldObject;
|
this.cachedNetworkers[transportType] = oldObject;
|
||||||
@ -274,7 +290,7 @@ export class ApiManager {
|
|||||||
//const connectionType: ConnectionType = 'client';
|
//const connectionType: ConnectionType = 'client';
|
||||||
|
|
||||||
const transportType = this.getTransportType(connectionType);
|
const transportType = this.getTransportType(connectionType);
|
||||||
if(!this.cachedNetworkers.hasOwnProperty(transportType)) {
|
if(!this.cachedNetworkers[transportType]) {
|
||||||
this.cachedNetworkers[transportType] = {
|
this.cachedNetworkers[transportType] = {
|
||||||
client: {},
|
client: {},
|
||||||
download: {},
|
download: {},
|
||||||
@ -312,7 +328,7 @@ export class ApiManager {
|
|||||||
const ak: DcAuthKey = `dc${dcId}_auth_key` as any;
|
const ak: DcAuthKey = `dc${dcId}_auth_key` as any;
|
||||||
const ss: DcServerSalt = `dc${dcId}_server_salt` as any;
|
const ss: DcServerSalt = `dc${dcId}_server_salt` as any;
|
||||||
|
|
||||||
const transport = this.chooseServer(dcId, connectionType, transportType);
|
let transport = this.chooseServer(dcId, connectionType, transportType);
|
||||||
return this.gettingNetworkers[getKey] = Promise.all([ak, ss].map(key => sessionStorage.get(key)))
|
return this.gettingNetworkers[getKey] = Promise.all([ak, ss].map(key => sessionStorage.get(key)))
|
||||||
.then(async([authKeyHex, serverSaltHex]) => {
|
.then(async([authKeyHex, serverSaltHex]) => {
|
||||||
let networker: MTPNetworker;
|
let networker: MTPNetworker;
|
||||||
@ -325,19 +341,17 @@ export class ApiManager {
|
|||||||
const authKeyId = (await CryptoWorker.invokeCrypto('sha1-hash', authKey)).slice(-8);
|
const authKeyId = (await CryptoWorker.invokeCrypto('sha1-hash', authKey)).slice(-8);
|
||||||
const serverSalt = bytesFromHex(serverSaltHex);
|
const serverSalt = bytesFromHex(serverSaltHex);
|
||||||
|
|
||||||
networker = networkerFactory.getNetworker(dcId, authKey, authKeyId, serverSalt, transport, options);
|
networker = networkerFactory.getNetworker(dcId, authKey, authKeyId, serverSalt, options);
|
||||||
} else {
|
} else {
|
||||||
try { // if no saved state
|
try { // if no saved state
|
||||||
const auth = await authorizer.auth(dcId);
|
const auth = await authorizer.auth(dcId);
|
||||||
|
|
||||||
const storeObj = {
|
sessionStorage.set({
|
||||||
[ak]: bytesToHex(auth.authKey),
|
[ak]: bytesToHex(auth.authKey),
|
||||||
[ss]: bytesToHex(auth.serverSalt)
|
[ss]: bytesToHex(auth.serverSalt)
|
||||||
};
|
});
|
||||||
|
|
||||||
sessionStorage.set(storeObj);
|
networker = networkerFactory.getNetworker(dcId, auth.authKey, auth.authKeyId, auth.serverSalt, options);
|
||||||
|
|
||||||
networker = networkerFactory.getNetworker(dcId, auth.authKey, auth.authKeyId, auth.serverSalt, transport, options);
|
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
this.log('Get networker error', error, (error as Error).stack);
|
this.log('Get networker error', error, (error as Error).stack);
|
||||||
delete this.gettingNetworkers[getKey];
|
delete this.gettingNetworkers[getKey];
|
||||||
@ -345,6 +359,16 @@ export class ApiManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ! cannot get it before this promise because simultaneous changeTransport will change nothing
|
||||||
|
const newTransportType = this.getTransportType(connectionType);
|
||||||
|
if(newTransportType !== transportType) {
|
||||||
|
transport.destroy();
|
||||||
|
DcConfigurator.removeTransport(dcConfigurator.chosenServers, transport);
|
||||||
|
transport = this.chooseServer(dcId, connectionType, newTransportType);
|
||||||
|
}
|
||||||
|
|
||||||
|
networker.changeTransport(transport);
|
||||||
|
|
||||||
/* networker.onConnectionStatusChange = (online) => {
|
/* networker.onConnectionStatusChange = (online) => {
|
||||||
console.log('status:', online);
|
console.log('status:', online);
|
||||||
}; */
|
}; */
|
||||||
@ -377,7 +401,6 @@ export class ApiManager {
|
|||||||
networker.destroy();
|
networker.destroy();
|
||||||
networkerFactory.removeNetworker(networker);
|
networkerFactory.removeNetworker(networker);
|
||||||
DcConfigurator.removeTransport(this.cachedNetworkers, networker);
|
DcConfigurator.removeTransport(this.cachedNetworkers, networker);
|
||||||
DcConfigurator.removeTransport(dcConfigurator.chosenServers, networker.transport);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
networker.setDrainTimeout();
|
networker.setDrainTimeout();
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { TLSerialization, TLDeserialization } from "./tl_utils";
|
import { TLSerialization, TLDeserialization } from "./tl_utils";
|
||||||
import dcConfigurator from "./dcConfigurator";
|
import dcConfigurator, { TransportType } from "./dcConfigurator";
|
||||||
import rsaKeysManager from "./rsaKeysManager";
|
import rsaKeysManager from "./rsaKeysManager";
|
||||||
import timeManager from "./timeManager";
|
import timeManager from "./timeManager";
|
||||||
|
|
||||||
@ -24,6 +24,10 @@ import { addPadding } from "./bin_utils";
|
|||||||
import { Awaited, DcId } from "../../types";
|
import { Awaited, DcId } from "../../types";
|
||||||
import { ApiError } from "./apiManager";
|
import { ApiError } from "./apiManager";
|
||||||
|
|
||||||
|
/// #if MTPROTO_AUTO
|
||||||
|
import transportController from "./transports/controller";
|
||||||
|
/// #endif
|
||||||
|
|
||||||
/* let fNewNonce: any = bytesFromHex('8761970c24cb2329b5b2459752c502f3057cb7e8dbab200e526e8767fdc73b3c').reverse();
|
/* let fNewNonce: any = bytesFromHex('8761970c24cb2329b5b2459752c502f3057cb7e8dbab200e526e8767fdc73b3c').reverse();
|
||||||
let fNonce: any = bytesFromHex('b597720d11faa5914ef485c529cde414').reverse();
|
let fNonce: any = bytesFromHex('b597720d11faa5914ef485c529cde414').reverse();
|
||||||
let fResult: any = new Uint8Array(bytesFromHex('000000000000000001b473a0661b285e480000006324160514e4cd29c585f44e91a5fa110d7297b5c0c4134c84893db5715ecd56af5ed618082182053cc5de91cd00000015c4b51c02000000a5b7f709355fc30b216be86c022bb4c3'));
|
let fResult: any = new Uint8Array(bytesFromHex('000000000000000001b473a0661b285e480000006324160514e4cd29c585f44e91a5fa110d7297b5c0c4134c84893db5715ecd56af5ed618082182053cc5de91cd00000015c4b51c02000000a5b7f709355fc30b216be86c022bb4c3'));
|
||||||
@ -103,6 +107,12 @@ export class Authorizer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private log: ReturnType<typeof logger>;
|
private log: ReturnType<typeof logger>;
|
||||||
|
|
||||||
|
private transportType: TransportType;
|
||||||
|
|
||||||
|
/// #if MTPROTO_AUTO
|
||||||
|
private getTransportTypePromise: Promise<void>;
|
||||||
|
/// #endif
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.cached = {};
|
this.cached = {};
|
||||||
@ -122,7 +132,7 @@ export class Authorizer {
|
|||||||
resultArray.set(headerArray);
|
resultArray.set(headerArray);
|
||||||
resultArray.set(requestArray, headerArray.length);
|
resultArray.set(requestArray, headerArray.length);
|
||||||
|
|
||||||
const transport = dcConfigurator.chooseServer(dcId);
|
const transport = dcConfigurator.chooseServer(dcId, 'client', this.transportType);
|
||||||
const baseError = {
|
const baseError = {
|
||||||
code: 406,
|
code: 406,
|
||||||
type: 'NETWORK_BAD_RESPONSE'
|
type: 'NETWORK_BAD_RESPONSE'
|
||||||
@ -570,18 +580,27 @@ export class Authorizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// #if MTPROTO_AUTO
|
||||||
|
private getTransportType() {
|
||||||
|
if(this.getTransportTypePromise) return this.getTransportTypePromise;
|
||||||
|
return this.getTransportTypePromise = transportController.pingTransports().then(({websocket}) => {
|
||||||
|
this.transportType = websocket ? 'websocket' : 'https';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/// #endif
|
||||||
|
|
||||||
public auth(dcId: DcId) {
|
public auth(dcId: DcId) {
|
||||||
let promise = this.cached[dcId];
|
let promise = this.cached[dcId];
|
||||||
if(promise) {
|
if(promise) {
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!dcConfigurator.chooseServer(dcId)) {
|
|
||||||
throw new Error('[MT] No server found for dc ' + dcId);
|
|
||||||
}
|
|
||||||
|
|
||||||
promise = new Promise(async(resolve, reject) => {
|
promise = new Promise(async(resolve, reject) => {
|
||||||
|
/// #if MTPROTO_AUTO
|
||||||
|
await this.getTransportType();
|
||||||
|
/// #endif
|
||||||
|
|
||||||
let error: ApiError;
|
let error: ApiError;
|
||||||
let _try = 1;
|
let _try = 1;
|
||||||
while(_try++ <= 3) {
|
while(_try++ <= 3) {
|
||||||
|
@ -36,6 +36,7 @@ import { bigInt2str, rightShift_, str2bigInt } from '../../vendor/leemon';
|
|||||||
import { forEachReverse } from '../../helpers/array';
|
import { forEachReverse } from '../../helpers/array';
|
||||||
import { ConnectionStatus } from './connectionStatus';
|
import { ConnectionStatus } from './connectionStatus';
|
||||||
import ctx from '../../environment/ctx';
|
import ctx from '../../environment/ctx';
|
||||||
|
import dcConfigurator, { DcConfigurator } from './dcConfigurator';
|
||||||
|
|
||||||
//console.error('networker included!', new Error().stack);
|
//console.error('networker included!', new Error().stack);
|
||||||
|
|
||||||
@ -104,6 +105,7 @@ export default class MTPNetworker {
|
|||||||
/// #if MTPROTO_HAS_HTTP
|
/// #if MTPROTO_HAS_HTTP
|
||||||
private longPollInterval: number;
|
private longPollInterval: number;
|
||||||
private longPollPending: number;
|
private longPollPending: number;
|
||||||
|
private checkConnectionRetryAt: number;
|
||||||
private checkConnectionTimeout: number;
|
private checkConnectionTimeout: number;
|
||||||
private checkConnectionPeriod = 0;
|
private checkConnectionPeriod = 0;
|
||||||
private sleepAfter: number;
|
private sleepAfter: number;
|
||||||
@ -148,7 +150,6 @@ export default class MTPNetworker {
|
|||||||
private authKey: Uint8Array,
|
private authKey: Uint8Array,
|
||||||
private authKeyId: Uint8Array,
|
private authKeyId: Uint8Array,
|
||||||
serverSalt: Uint8Array,
|
serverSalt: Uint8Array,
|
||||||
transport: MTTransport,
|
|
||||||
options: InvokeApiOptions = {}
|
options: InvokeApiOptions = {}
|
||||||
) {
|
) {
|
||||||
this.authKeyUint8 = convertToUint8Array(this.authKey);
|
this.authKeyUint8 = convertToUint8Array(this.authKey);
|
||||||
@ -178,8 +179,6 @@ export default class MTPNetworker {
|
|||||||
// rootScope.offlineConnecting = true */
|
// rootScope.offlineConnecting = true */
|
||||||
// }
|
// }
|
||||||
|
|
||||||
this.changeTransport(transport);
|
|
||||||
|
|
||||||
// * handle outcoming dead socket, server will close the connection
|
// * handle outcoming dead socket, server will close the connection
|
||||||
// if((this.transport as TcpObfuscated).networker) {
|
// if((this.transport as TcpObfuscated).networker) {
|
||||||
// this.disconnectDelay = /* (this.transport as TcpObfuscated).retryTimeout */75;
|
// this.disconnectDelay = /* (this.transport as TcpObfuscated).retryTimeout */75;
|
||||||
@ -366,9 +365,9 @@ export default class MTPNetworker {
|
|||||||
public changeTransport(transport?: MTTransport) {
|
public changeTransport(transport?: MTTransport) {
|
||||||
const oldTransport = this.transport;
|
const oldTransport = this.transport;
|
||||||
if(oldTransport) {
|
if(oldTransport) {
|
||||||
if((oldTransport as TcpObfuscated).destroy) {
|
oldTransport.destroy();
|
||||||
(oldTransport as TcpObfuscated).destroy();
|
|
||||||
}
|
DcConfigurator.removeTransport(dcConfigurator.chosenServers, this.transport);
|
||||||
|
|
||||||
if(this.nextReqTimeout) {
|
if(this.nextReqTimeout) {
|
||||||
clearTimeout(this.nextReqTimeout);
|
clearTimeout(this.nextReqTimeout);
|
||||||
@ -394,22 +393,25 @@ export default class MTPNetworker {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transport.networker = this;
|
||||||
|
|
||||||
/// #if MTPROTO_HAS_HTTP
|
/// #if MTPROTO_HAS_HTTP
|
||||||
/// #if MTPROTO_HAS_WS
|
/// #if MTPROTO_HAS_WS
|
||||||
if(transport instanceof HTTP) {
|
if(transport instanceof HTTP) {
|
||||||
/// #endif
|
/// #endif
|
||||||
this.longPollInterval = ctx.setInterval(this.checkLongPoll, 10000);
|
this.longPollInterval = ctx.setInterval(this.checkLongPoll, 10000);
|
||||||
this.checkLongPoll();
|
this.checkLongPoll();
|
||||||
|
this.checkConnection('changed transport');
|
||||||
/// #if MTPROTO_HAS_WS
|
/// #if MTPROTO_HAS_WS
|
||||||
}
|
}
|
||||||
/// #endif
|
/// #endif
|
||||||
/// #endif
|
/// #endif
|
||||||
|
|
||||||
transport.networker = this;
|
if(transport.connected && (transport as TcpObfuscated).connection) {
|
||||||
|
|
||||||
if((transport as TcpObfuscated).connected) {
|
|
||||||
this.setConnectionStatus(ConnectionStatus.Connected);
|
this.setConnectionStatus(ConnectionStatus.Connected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.resend();
|
||||||
}
|
}
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
@ -419,12 +421,16 @@ export default class MTPNetworker {
|
|||||||
public forceReconnectTimeout() {
|
public forceReconnectTimeout() {
|
||||||
if((this.transport as TcpObfuscated).reconnect) {
|
if((this.transport as TcpObfuscated).reconnect) {
|
||||||
(this.transport as TcpObfuscated).reconnect();
|
(this.transport as TcpObfuscated).reconnect();
|
||||||
|
} else {
|
||||||
|
this.resend();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public forceReconnect() {
|
public forceReconnect() {
|
||||||
if((this.transport as TcpObfuscated).forceReconnect) {
|
if((this.transport as TcpObfuscated).forceReconnect) {
|
||||||
(this.transport as TcpObfuscated).forceReconnect();
|
(this.transport as TcpObfuscated).forceReconnect();
|
||||||
|
} else {
|
||||||
|
this.checkConnection('force reconnect');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,6 +609,10 @@ export default class MTPNetworker {
|
|||||||
body: serializer.getBytes(true)
|
body: serializer.getBytes(true)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if(this.offline) {
|
||||||
|
this.setConnectionStatus(ConnectionStatus.Connecting);
|
||||||
|
}
|
||||||
|
|
||||||
this.sendEncryptedRequest(pingMessage).then(() => {
|
this.sendEncryptedRequest(pingMessage).then(() => {
|
||||||
this.toggleOffline(false);
|
this.toggleOffline(false);
|
||||||
}, () => {
|
}, () => {
|
||||||
@ -612,91 +622,83 @@ export default class MTPNetworker {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
private toggleOffline(enabled: boolean) {
|
private toggleOffline(offline: boolean) {
|
||||||
// this.log('toggle ', enabled, this.dcId, this.iii)
|
if(this.offline !== offline) {
|
||||||
if(this.offline !== undefined && this.offline === enabled) {
|
this.offline = offline;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.offline = enabled;
|
|
||||||
|
|
||||||
if(this.offline) {
|
if(offline) {
|
||||||
clearTimeout(this.nextReqTimeout);
|
clearTimeout(this.nextReqTimeout);
|
||||||
this.nextReqTimeout = 0;
|
this.nextReqTimeout = 0;
|
||||||
this.nextReq = 0;
|
this.nextReq = 0;
|
||||||
|
|
||||||
if(this.checkConnectionPeriod < 1.5) {
|
if(this.checkConnectionPeriod < 1.5) {
|
||||||
this.checkConnectionPeriod = 0;
|
this.checkConnectionPeriod = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const delay = this.checkConnectionPeriod * 1000 | 0;
|
||||||
|
this.checkConnectionRetryAt = Date.now() + delay;
|
||||||
|
this.setConnectionStatus(ConnectionStatus.Closed, this.checkConnectionRetryAt);
|
||||||
|
this.checkConnectionTimeout = ctx.setTimeout(this.checkConnection, delay);
|
||||||
|
this.checkConnectionPeriod = Math.min(30, (1 + this.checkConnectionPeriod) * 1.5);
|
||||||
|
|
||||||
|
/// #if !MTPROTO_WORKER
|
||||||
|
document.body.addEventListener('online', this.checkConnection, false);
|
||||||
|
document.body.addEventListener('focus', this.checkConnection, false);
|
||||||
|
/// #endif
|
||||||
|
} else {
|
||||||
|
this.setConnectionStatus(ConnectionStatus.Connected);
|
||||||
|
this.checkLongPoll();
|
||||||
|
|
||||||
|
this.scheduleRequest();
|
||||||
|
|
||||||
|
/// #if !MTPROTO_WORKER
|
||||||
|
document.body.removeEventListener('online', this.checkConnection);
|
||||||
|
document.body.removeEventListener('focus', this.checkConnection);
|
||||||
|
/// #endif
|
||||||
|
|
||||||
|
clearTimeout(this.checkConnectionTimeout);
|
||||||
|
this.checkConnectionTimeout = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.checkConnectionTimeout = ctx.setTimeout(this.checkConnection, this.checkConnectionPeriod * 1000 | 0);
|
|
||||||
this.checkConnectionPeriod = Math.min(30, (1 + this.checkConnectionPeriod) * 1.5);
|
|
||||||
|
|
||||||
/// #if !MTPROTO_WORKER
|
|
||||||
document.body.addEventListener('online', this.checkConnection, false);
|
|
||||||
document.body.addEventListener('focus', this.checkConnection, false);
|
|
||||||
/// #endif
|
|
||||||
} else {
|
|
||||||
this.checkLongPoll();
|
|
||||||
|
|
||||||
this.scheduleRequest();
|
|
||||||
|
|
||||||
/// #if !MTPROTO_WORKER
|
|
||||||
document.body.removeEventListener('online', this.checkConnection);
|
|
||||||
document.body.removeEventListener('focus', this.checkConnection);
|
|
||||||
/// #endif
|
|
||||||
|
|
||||||
clearTimeout(this.checkConnectionTimeout);
|
|
||||||
this.checkConnectionTimeout = undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setConnectionStatus(offline ? ConnectionStatus.Closed : ConnectionStatus.Connected, offline ? this.checkConnectionRetryAt : undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleSentEncryptedRequestHTTP(promise: ReturnType<MTPNetworker['sendEncryptedRequest']>, message: MTMessage, noResponseMsgs: string[]) {
|
private handleSentEncryptedRequestHTTP(promise: ReturnType<MTPNetworker['sendEncryptedRequest']>, message: MTMessage, noResponseMsgs: string[]) {
|
||||||
|
// let timeout = setTimeout(() => {
|
||||||
|
// this.log.error('handleSentEncryptedRequestHTTP timeout', promise, message, noResponseMsgs);
|
||||||
|
// }, 5e3);
|
||||||
|
|
||||||
promise.then((result) => {
|
promise.then((result) => {
|
||||||
this.toggleOffline(false);
|
this.toggleOffline(false);
|
||||||
// this.log('parse for', message);
|
// this.log('parse for', message);
|
||||||
this.parseResponse(result).then((response) => {
|
return this.parseResponse(result).then((response) => {
|
||||||
if(Modes.debug) {
|
this.debug && this.log.debug('Server response', response);
|
||||||
this.log.debug('Server response', response);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.processMessage(response.response, response.messageId, response.sessionId);
|
this.processMessage(response.response, response.messageId, response.sessionId);
|
||||||
|
|
||||||
noResponseMsgs.forEach((msgId) => {
|
|
||||||
if(this.sentMessages[msgId]) {
|
|
||||||
const deferred = this.sentMessages[msgId].deferred;
|
|
||||||
delete this.sentMessages[msgId];
|
|
||||||
deferred.resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.checkLongPoll();
|
this.checkLongPoll();
|
||||||
|
|
||||||
this.checkConnectionPeriod = Math.max(1.1, Math.sqrt(this.checkConnectionPeriod));
|
this.checkConnectionPeriod = Math.max(1.1, Math.sqrt(this.checkConnectionPeriod));
|
||||||
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
this.log.error('Encrypted request failed', error, message);
|
this.log.error('Encrypted request failed', error, message);
|
||||||
|
|
||||||
if(message.container) {
|
this.pushResend(message.msg_id);
|
||||||
message.inner.forEach((msgId) => {
|
this.toggleOffline(true);
|
||||||
this.pendingMessages[msgId] = 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
delete this.sentMessages[message.msg_id];
|
return false;
|
||||||
} else {
|
}).then((shouldResolve) => {
|
||||||
this.pendingMessages[message.msg_id] = 0;
|
// clearTimeout(timeout);
|
||||||
}
|
|
||||||
|
|
||||||
noResponseMsgs.forEach((msgId) => {
|
noResponseMsgs.forEach((msgId) => {
|
||||||
if(this.sentMessages[msgId]) {
|
if(this.sentMessages[msgId]) {
|
||||||
const deferred = this.sentMessages[msgId].deferred;
|
const deferred = this.sentMessages[msgId].deferred;
|
||||||
delete this.sentMessages[msgId];
|
delete this.sentMessages[msgId];
|
||||||
delete this.pendingMessages[msgId];
|
delete this.pendingMessages[msgId];
|
||||||
deferred.reject();
|
shouldResolve ? deferred.resolve() : deferred.reject();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.toggleOffline(true);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/// #endif
|
/// #endif
|
||||||
@ -1187,37 +1189,40 @@ export default class MTPNetworker {
|
|||||||
|
|
||||||
private sendEncryptedRequest(message: MTMessage) {
|
private sendEncryptedRequest(message: MTMessage) {
|
||||||
return this.getEncryptedOutput(message).then(requestData => {
|
return this.getEncryptedOutput(message).then(requestData => {
|
||||||
this.debug && this.log.debug('sendEncryptedRequest: launching message into space:', message, [message.msg_id].concat(message.inner || []));
|
this.debug && this.log.debug('sendEncryptedRequest: launching message into space:', message, [message.msg_id].concat(message.inner || []), requestData.length);
|
||||||
|
|
||||||
const promise: Promise<Uint8Array> = this.transport.send(requestData) as any;
|
const promise: Promise<Uint8Array> = this.transport.send(requestData) as any;
|
||||||
|
// this.debug && this.log.debug('sendEncryptedRequest: launched message into space:', message, promise);
|
||||||
|
|
||||||
/// #if !MTPROTO_HAS_HTTP
|
/// #if !MTPROTO_HAS_HTTP
|
||||||
return promise;
|
return promise;
|
||||||
/// #else
|
/// #else
|
||||||
|
|
||||||
/// #if MTPROTO_HAS_WS
|
/// #if MTPROTO_HAS_WS
|
||||||
if(!(this.transport instanceof HTTP)) return promise;
|
if(!(this.transport instanceof HTTP)) return promise;
|
||||||
/// #endif
|
/// #endif
|
||||||
|
|
||||||
const baseError = {
|
const baseError = {
|
||||||
code: 406,
|
code: 406,
|
||||||
type: 'NETWORK_BAD_RESPONSE',
|
type: 'NETWORK_BAD_RESPONSE',
|
||||||
transport: this.transport
|
transport: this.transport
|
||||||
};
|
};
|
||||||
|
|
||||||
return promise.then((result) => {
|
return promise.then((result) => {
|
||||||
if(!result || !result.byteLength) {
|
if(!result?.byteLength) {
|
||||||
return Promise.reject(baseError);
|
throw baseError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this.debug && this.log.debug('sendEncryptedRequest: got response for:', message, [message.msg_id].concat(message.inner || []));
|
||||||
return result;
|
return result;
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
if(!error.message && !error.type) {
|
if(!error.message && !error.type) {
|
||||||
error = Object.assign(baseError, {
|
error = Object.assign(baseError, {
|
||||||
type: 'NETWORK_BAD_REQUEST',
|
type: 'NETWORK_BAD_REQUEST',
|
||||||
originalError: error
|
originalError: error
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return Promise.reject(error);
|
|
||||||
|
throw error;
|
||||||
});
|
});
|
||||||
/// #endif
|
/// #endif
|
||||||
});
|
});
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
import type { ConnectionStatusChange } from "./connectionStatus";
|
import type { ConnectionStatusChange } from "./connectionStatus";
|
||||||
import MTPNetworker from "./networker";
|
import MTPNetworker from "./networker";
|
||||||
import { InvokeApiOptions } from "../../types";
|
import { InvokeApiOptions } from "../../types";
|
||||||
import MTTransport from "./transports/transport";
|
|
||||||
import App from "../../config/app";
|
import App from "../../config/app";
|
||||||
import { MOUNT_CLASS_TO } from "../../config/debug";
|
import { MOUNT_CLASS_TO } from "../../config/debug";
|
||||||
|
import { indexOfAndSplice } from "../../helpers/array";
|
||||||
|
|
||||||
export class NetworkerFactory {
|
export class NetworkerFactory {
|
||||||
private networkers: MTPNetworker[] = [];
|
private networkers: MTPNetworker[] = [];
|
||||||
@ -25,19 +25,16 @@ export class NetworkerFactory {
|
|||||||
public userAgent = navigator.userAgent;
|
public userAgent = navigator.userAgent;
|
||||||
|
|
||||||
public removeNetworker(networker: MTPNetworker) {
|
public removeNetworker(networker: MTPNetworker) {
|
||||||
const idx = this.networkers.indexOf(networker);
|
indexOfAndSplice(this.networkers, networker);
|
||||||
if(idx !== -1) {
|
|
||||||
this.networkers.splice(idx, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public setUpdatesProcessor(callback: (obj: any) => void) {
|
public setUpdatesProcessor(callback: (obj: any) => void) {
|
||||||
this.updatesProcessor = callback;
|
this.updatesProcessor = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getNetworker(dcId: number, authKey: Uint8Array, authKeyId: Uint8Array, serverSalt: Uint8Array, transport: MTTransport, options: InvokeApiOptions) {
|
public getNetworker(dcId: number, authKey: Uint8Array, authKeyId: Uint8Array, serverSalt: Uint8Array, options: InvokeApiOptions) {
|
||||||
//console.log('NetworkerFactory: creating new instance of MTPNetworker:', dcId, options);
|
//console.log('NetworkerFactory: creating new instance of MTPNetworker:', dcId, options);
|
||||||
const networker = new MTPNetworker(dcId, authKey, authKeyId, serverSalt, transport, options);
|
const networker = new MTPNetworker(dcId, authKey, authKeyId, serverSalt, options);
|
||||||
this.networkers.push(networker);
|
this.networkers.push(networker);
|
||||||
return networker;
|
return networker;
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,110 @@
|
|||||||
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { TransportType } from "../dcConfigurator";
|
import App from "../../../config/app";
|
||||||
|
import { deferredPromise } from "../../../helpers/cancellablePromise";
|
||||||
|
import EventListenerBase from "../../../helpers/eventListenerBase";
|
||||||
|
import { pause } from "../../../helpers/schedulers/pause";
|
||||||
|
import dcConfigurator, { TransportType } from "../dcConfigurator";
|
||||||
|
import type HTTP from "./http";
|
||||||
|
import type TcpObfuscated from "./tcpObfuscated";
|
||||||
|
import MTTransport from "./transport";
|
||||||
|
|
||||||
export class MTTransportController {
|
export class MTTransportController extends EventListenerBase<{
|
||||||
|
change: (opened: MTTransportController['opened']) => void,
|
||||||
|
transport: (type: TransportType) => void
|
||||||
|
}> {
|
||||||
private opened: Map<TransportType, number>;
|
private opened: Map<TransportType, number>;
|
||||||
|
private transports: {[k in TransportType]?: MTTransport};
|
||||||
|
private pinging: boolean;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
super(true);
|
||||||
|
|
||||||
this.opened = new Map();
|
this.opened = new Map();
|
||||||
|
/* this.addEventListener('change', (opened) => {
|
||||||
|
this.dispatchEvent('transport', opened.get('websocket') || !opened.get('https') ? 'websocket' : 'https');
|
||||||
|
}); */
|
||||||
|
|
||||||
|
this.addEventListener('change', (opened) => {
|
||||||
|
if(!opened.get('websocket')) {
|
||||||
|
this.waitForWebSocket();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.waitForWebSocket();
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setTransportOpened(type: TransportType, value: boolean) {
|
public async pingTransports() {
|
||||||
|
const timeout = 2000;
|
||||||
|
const transports: {[k in TransportType]?: MTTransport} = this.transports = {
|
||||||
|
https: dcConfigurator.chooseServer(App.baseDcId, 'client', 'https', false),
|
||||||
|
websocket: dcConfigurator.chooseServer(App.baseDcId, 'client', 'websocket', false)
|
||||||
|
};
|
||||||
|
|
||||||
|
const httpPromise = deferredPromise<boolean>();
|
||||||
|
((this.transports.https as HTTP)._send(new Uint8Array(), 'no-cors') as any as Promise<any>)
|
||||||
|
.then(() => httpPromise.resolve(true), () => httpPromise.resolve(false));
|
||||||
|
setTimeout(() => httpPromise.resolve(false), timeout);
|
||||||
|
|
||||||
|
const websocketPromise = deferredPromise<boolean>();
|
||||||
|
const socket = transports.websocket as TcpObfuscated;
|
||||||
|
socket.setAutoReconnect(false);
|
||||||
|
socket.connection.addEventListener('close', () => websocketPromise.resolve(false), {once: true});
|
||||||
|
socket.connection.addEventListener('open', () => websocketPromise.resolve(true), {once: true});
|
||||||
|
setTimeout(() => websocketPromise.resolve(false), timeout);
|
||||||
|
|
||||||
|
const [isHttpAvailable, isWebSocketAvailable] = await Promise.all([httpPromise, websocketPromise]);
|
||||||
|
|
||||||
|
for(const transportType in transports) {
|
||||||
|
const transport = transports[transportType as TransportType];
|
||||||
|
transport.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
https: isHttpAvailable || this.opened.get('https') > 0,
|
||||||
|
websocket: isWebSocketAvailable || this.opened.get('websocket') > 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async waitForWebSocket() {
|
||||||
|
if(this.pinging) return;
|
||||||
|
this.pinging = true;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
const {https, websocket} = await this.pingTransports();
|
||||||
|
if(https || websocket) {
|
||||||
|
this.dispatchEvent('transport', websocket || !https ? 'websocket' : 'https');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(websocket) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
await pause(10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pinging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setTransportValue(type: TransportType, value: boolean) {
|
||||||
let length = this.opened.get(type) || 0;
|
let length = this.opened.get(type) || 0;
|
||||||
|
|
||||||
length += value ? 1 : -1;
|
length += value ? 1 : -1;
|
||||||
|
|
||||||
this.opened.set(type, length);
|
this.opened.set(type, length);
|
||||||
|
this.dispatchEvent('change', this.opened);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setTransportOpened(type: TransportType) {
|
||||||
|
return this.setTransportValue(type, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setTransportClosed(type: TransportType) {
|
||||||
|
return this.setTransportValue(type, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new MTTransportController();
|
const transportController = new MTTransportController();
|
||||||
|
export default transportController;
|
||||||
|
@ -6,9 +6,14 @@
|
|||||||
|
|
||||||
import { pause } from '../../../helpers/schedulers/pause';
|
import { pause } from '../../../helpers/schedulers/pause';
|
||||||
import { DcId } from '../../../types';
|
import { DcId } from '../../../types';
|
||||||
import { logger } from '../../logger';
|
import { logger, LogTypes } from '../../logger';
|
||||||
import type MTPNetworker from '../networker';
|
import type MTPNetworker from '../networker';
|
||||||
import MTTransport from './transport';
|
import MTTransport from './transport';
|
||||||
|
import Modes from '../../../config/modes';
|
||||||
|
|
||||||
|
/// #if MTPROTO_AUTO
|
||||||
|
import transportController from './controller';
|
||||||
|
/// #endif
|
||||||
|
|
||||||
export default class HTTP implements MTTransport {
|
export default class HTTP implements MTTransport {
|
||||||
public networker: MTPNetworker;
|
public networker: MTPNetworker;
|
||||||
@ -20,14 +25,28 @@ export default class HTTP implements MTTransport {
|
|||||||
body: Uint8Array
|
body: Uint8Array
|
||||||
}> = [];
|
}> = [];
|
||||||
private releasing: boolean;
|
private releasing: boolean;
|
||||||
|
|
||||||
|
public connected: boolean;
|
||||||
|
private destroyed: boolean;
|
||||||
|
private debug: boolean;
|
||||||
|
|
||||||
constructor(protected dcId: DcId, protected url: string, logSuffix: string) {
|
constructor(protected dcId: DcId, protected url: string, logSuffix: string) {
|
||||||
this.log = logger(`HTTP-${dcId}` + logSuffix);
|
this.debug = Modes.debug && false;
|
||||||
|
|
||||||
|
let logTypes = LogTypes.Error | LogTypes.Log;
|
||||||
|
if(this.debug) logTypes |= LogTypes.Debug;
|
||||||
|
|
||||||
|
this.log = logger(`HTTP-${dcId}` + logSuffix, logTypes);
|
||||||
|
this.log('constructor');
|
||||||
|
|
||||||
|
this.connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _send(body: Uint8Array) {
|
public _send(body: Uint8Array, mode?: RequestMode) {
|
||||||
return fetch(this.url, {method: 'POST', body}).then(response => {
|
this.debug && this.log.debug('-> body length to send:', body.length);
|
||||||
if(response.status !== 200) {
|
|
||||||
|
return fetch(this.url, {method: 'POST', body, mode}).then(response => {
|
||||||
|
if(response.status !== 200 && !mode) {
|
||||||
response.arrayBuffer().then(buffer => {
|
response.arrayBuffer().then(buffer => {
|
||||||
this.log.error('not 200',
|
this.log.error('not 200',
|
||||||
new TextDecoder("utf-8").decode(new Uint8Array(buffer)));
|
new TextDecoder("utf-8").decode(new Uint8Array(buffer)));
|
||||||
@ -36,6 +55,8 @@ export default class HTTP implements MTTransport {
|
|||||||
throw response;
|
throw response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setConnected(true);
|
||||||
|
|
||||||
// * test resending by dropping random request
|
// * test resending by dropping random request
|
||||||
// if(Math.random() > .5) {
|
// if(Math.random() > .5) {
|
||||||
// throw 'asd';
|
// throw 'asd';
|
||||||
@ -44,9 +65,31 @@ export default class HTTP implements MTTransport {
|
|||||||
return response.arrayBuffer().then(buffer => {
|
return response.arrayBuffer().then(buffer => {
|
||||||
return new Uint8Array(buffer);
|
return new Uint8Array(buffer);
|
||||||
});
|
});
|
||||||
|
}, (err) => {
|
||||||
|
this.setConnected(false);
|
||||||
|
throw err;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setConnected(connected: boolean) {
|
||||||
|
if(this.connected === connected || this.destroyed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.connected = connected;
|
||||||
|
|
||||||
|
/// #if MTPROTO_AUTO
|
||||||
|
transportController.setTransportValue('https', connected);
|
||||||
|
/// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public destroy() {
|
||||||
|
this.setConnected(false);
|
||||||
|
this.destroyed = true;
|
||||||
|
this.pending.forEach(pending => pending.reject());
|
||||||
|
this.pending.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public send(body: Uint8Array) {
|
public send(body: Uint8Array) {
|
||||||
if(this.networker) {
|
if(this.networker) {
|
||||||
return this._send(body);
|
return this._send(body);
|
||||||
|
@ -12,6 +12,10 @@ import MTTransport, { MTConnection, MTConnectionConstructable } from "./transpor
|
|||||||
import intermediatePacketCodec from './intermediate';
|
import intermediatePacketCodec from './intermediate';
|
||||||
import { ConnectionStatus } from "../connectionStatus";
|
import { ConnectionStatus } from "../connectionStatus";
|
||||||
|
|
||||||
|
/// #if MTPROTO_AUTO
|
||||||
|
import transportController from "./controller";
|
||||||
|
/// #endif
|
||||||
|
|
||||||
export default class TcpObfuscated implements MTTransport {
|
export default class TcpObfuscated implements MTTransport {
|
||||||
private codec = intermediatePacketCodec;
|
private codec = intermediatePacketCodec;
|
||||||
private obfuscation = new Obfuscation();
|
private obfuscation = new Obfuscation();
|
||||||
@ -29,7 +33,7 @@ export default class TcpObfuscated implements MTTransport {
|
|||||||
private log: ReturnType<typeof logger>;
|
private log: ReturnType<typeof logger>;
|
||||||
public connected = false;
|
public connected = false;
|
||||||
private lastCloseTime: number;
|
private lastCloseTime: number;
|
||||||
private connection: MTConnection;
|
public connection: MTConnection;
|
||||||
|
|
||||||
private autoReconnect = true;
|
private autoReconnect = true;
|
||||||
private reconnectTimeout: number;
|
private reconnectTimeout: number;
|
||||||
@ -53,6 +57,10 @@ export default class TcpObfuscated implements MTTransport {
|
|||||||
private onOpen = () => {
|
private onOpen = () => {
|
||||||
this.connected = true;
|
this.connected = true;
|
||||||
|
|
||||||
|
/// #if MTPROTO_AUTO
|
||||||
|
transportController.setTransportOpened('websocket');
|
||||||
|
/// #endif
|
||||||
|
|
||||||
const initPayload = this.obfuscation.init(this.codec);
|
const initPayload = this.obfuscation.init(this.codec);
|
||||||
|
|
||||||
this.connection.send(initPayload);
|
this.connection.send(initPayload);
|
||||||
@ -136,6 +144,12 @@ export default class TcpObfuscated implements MTTransport {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public clear() {
|
public clear() {
|
||||||
|
/// #if MTPROTO_AUTO
|
||||||
|
if(this.connected) {
|
||||||
|
transportController.setTransportClosed('websocket');
|
||||||
|
}
|
||||||
|
/// #endif
|
||||||
|
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
|
|
||||||
if(this.connection) {
|
if(this.connection) {
|
||||||
@ -183,6 +197,13 @@ export default class TcpObfuscated implements MTTransport {
|
|||||||
public destroy() {
|
public destroy() {
|
||||||
this.setAutoReconnect(false);
|
this.setAutoReconnect(false);
|
||||||
this.close();
|
this.close();
|
||||||
|
|
||||||
|
this.pending.forEach(pending => {
|
||||||
|
if(pending.reject) {
|
||||||
|
pending.reject();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.pending.length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public close() {
|
public close() {
|
||||||
|
@ -10,6 +10,8 @@ import type MTPNetworker from "../networker";
|
|||||||
export default interface MTTransport {
|
export default interface MTTransport {
|
||||||
networker: MTPNetworker;
|
networker: MTPNetworker;
|
||||||
send: (data: Uint8Array) => void;
|
send: (data: Uint8Array) => void;
|
||||||
|
connected: boolean;
|
||||||
|
destroy: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MTConnection extends EventListenerBase<{
|
export interface MTConnection extends EventListenerBase<{
|
||||||
@ -17,7 +19,7 @@ export interface MTConnection extends EventListenerBase<{
|
|||||||
message: (buffer: ArrayBuffer) => any,
|
message: (buffer: ArrayBuffer) => any,
|
||||||
close: () => void,
|
close: () => void,
|
||||||
}> {
|
}> {
|
||||||
send: (data: Uint8Array) => void;
|
send: MTTransport['send'];
|
||||||
close: () => void;
|
close: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,9 @@ import Modes from '../../../config/modes';
|
|||||||
import EventListenerBase from '../../../helpers/eventListenerBase';
|
import EventListenerBase from '../../../helpers/eventListenerBase';
|
||||||
import { MTConnection } from './transport';
|
import { MTConnection } from './transport';
|
||||||
|
|
||||||
|
// let closeSocketBefore = Date.now() + 30e3;
|
||||||
|
// let closeSocketAfter = Date.now() + 10e3;
|
||||||
|
|
||||||
export default class Socket extends EventListenerBase<{
|
export default class Socket extends EventListenerBase<{
|
||||||
open: () => void,
|
open: () => void,
|
||||||
message: (buffer: ArrayBuffer) => any,
|
message: (buffer: ArrayBuffer) => any,
|
||||||
@ -49,6 +52,11 @@ export default class Socket extends EventListenerBase<{
|
|||||||
this.ws.addEventListener('close', this.handleClose);
|
this.ws.addEventListener('close', this.handleClose);
|
||||||
this.ws.addEventListener('error', this.handleError);
|
this.ws.addEventListener('error', this.handleError);
|
||||||
this.ws.addEventListener('message', this.handleMessage);
|
this.ws.addEventListener('message', this.handleMessage);
|
||||||
|
|
||||||
|
// if(Date.now() < closeSocketBefore) {
|
||||||
|
// if(Date.now() >= closeSocketAfter) {
|
||||||
|
// this.ws.close();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public close() {
|
public close() {
|
||||||
|
@ -17,11 +17,17 @@ if(devMode) {
|
|||||||
console.log('DEVMODE IS ON!');
|
console.log('DEVMODE IS ON!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MTPROTO_HTTP = false;
|
||||||
|
const MTPROTO_AUTO = true;
|
||||||
|
|
||||||
const opts = {
|
const opts = {
|
||||||
MTPROTO_WORKER: true,
|
MTPROTO_WORKER: true,
|
||||||
MTPROTO_SW: false,
|
MTPROTO_SW: false,
|
||||||
MTPROTO_HTTP: false,
|
MTPROTO_HTTP: MTPROTO_HTTP,
|
||||||
MTPROTO_HTTP_UPLOAD: false,
|
MTPROTO_HTTP_UPLOAD: false,
|
||||||
|
MTPROTO_AUTO: MTPROTO_AUTO, // use HTTPS when WS is unavailable
|
||||||
|
MTPROTO_HAS_HTTP: MTPROTO_AUTO,
|
||||||
|
MTPROTO_HAS_WS: MTPROTO_AUTO || !MTPROTO_HTTP,
|
||||||
DEBUG: devMode,
|
DEBUG: devMode,
|
||||||
version: 3,
|
version: 3,
|
||||||
'ifdef-verbose': devMode, // add this for verbose output
|
'ifdef-verbose': devMode, // add this for verbose output
|
||||||
|
Loading…
x
Reference in New Issue
Block a user