changed to async

This commit is contained in:
2021-05-24 13:33:46 +02:00
parent 0601f52661
commit eea681d435
3 changed files with 130 additions and 73 deletions

View File

@ -15,47 +15,51 @@ export class Domain {
this.name = jsonData.name;
this.id = jsonData.id;
this.servers = [];
for (let domainServer of domainServers) {
for (const domainServer of domainServers) {
this.servers.push(new DomainServer(domainServer));
}
this.invalidServers = [];
}
static async fromName(domainName) {
return fetch(`https://${domainName}/.well-known/usimp.json`, {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 2000);
let response = await fetch(`https://${domainName}/.well-known/usimp.json`, {
redirect: "manual",
}).then(response => {
if (response.ok) {
return response.json();
} else {
throw "Invalid response";
}
}).then(data => {
return new Domain(data.domain, data.domain_servers);
signal: controller.signal,
});
clearTimeout(timer);
if (!response.ok) {
throw Error("Invalid response");
}
const data = await response.json();
return new Domain(data.domain, data.domain_servers);
}
chooseDomainServer() {
if (this.servers.length === 0) throw Error("No domain servers specified");
this.servers.filter(srv => this.invalidServers.map(srv => srv.id).includes(srv.id));
if (this.servers.length === 0) throw Error("No domain servers reachable");
if (this.servers.length === 1) return this.servers[0];
const servers = this.servers.filter(srv => !this.invalidServers.map(srv => srv.id).includes(srv.id));
if (servers.length === 0) throw Error("No domain servers reachable");
if (servers.length === 1) return servers[0];
let priority = this.servers.reduce((min, srv) => Math.min(min, srv.priority), Infinity);
let domainServers = this.servers.filter(srv => srv.priority === priority);
if (domainServers.length === 1) return this.servers[0];
const priority = servers.reduce((min, srv) => Math.min(min, srv.priority), Infinity);
const domainServers = servers.filter(srv => srv.priority === priority);
if (domainServers.length === 1) return servers[0];
let totalWeight = domainServers.reduce((total, srv) => total + srv.weight, 0);
let w = Math.floor(Math.random() * totalWeight);
const totalWeight = domainServers.reduce((total, srv) => total + srv.weight, 0);
const w = Math.floor(Math.random() * totalWeight);
let accumulator = 0;
for (let srv of domainServers) {
for (const srv of domainServers) {
accumulator += srv.weight;
if (w < accumulator) return srv;
}
throw "Domain server selection did not work correctly";
throw Error("Domain server selection did not work correctly");
}
}
@ -107,37 +111,51 @@ export class Session {
constructor(domain) {
this.domain = domain;
this.server = domain.chooseDomainServer();
this.numRequests = 0;
}
const host = this.server.host;
const protocols = this.server.protocols;
async chooseDomainServer() {
while (!this.server) {
this.server = this.domain.chooseDomainServer();
/*
if ("wss" in protocols) {
this.wsConnection = new WebSocket(`wss://${host}:${protocols.wss}/_usimp/websocket`, ["usimp"]);
} else if ("ws" in protocols) {
this.wsConnection = new WebSocket(`ws://${host}:${protocols.ws}/_usimp/websocket`, ["usimp"])
}
*/
const host = this.server.host;
const protocols = this.server.protocols;
if ("https" in protocols) {
this.httpBaseUrl = `https://${host}:${protocols.https}/_usimp`;
} else if ("http" in protocols) {
this.httpBaseUrl = `http://${host}:${protocols.http}/_usimp`;
} else {
throw "Domain server provides no supported transport protocols";
/*
if ("wss" in protocols) {
this.wsConnection = new WebSocket(`wss://${host}:${protocols.wss}/_usimp/websocket`, ["usimp"]);
}
*/
// TODO http -> https
if ("http" in protocols) {
this.httpBaseUrl = `http://${host}:${protocols.http}/_usimp`;
try {
return await this.ping();
} catch {
this.domain.invalidServers.push(this.server);
this.server = null;
}
} else {
console.warn(`Domain server ${this.server} does not support 'https' transport protocol`);
this.domain.invalidServers.push(this.server);
this.server = null;
}
}
}
send(endpoint, data) {
async send(endpoint, data, timeout = 2000, forceHttp = false) {
this.numRequests++;
if (this.wsConnection) {
if (!forceHttp && this.wsConnection) {
this.wsConnection.send(JSON.stringify({
'request_num': this.numRequests,
'data': data
}));
} else {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeout);
let headers = {
'Content-Type': 'application/json',
'To-Domain': this.domain.id,
@ -147,28 +165,45 @@ export class Session {
headers['Authorization'] = `usimp ${this.token}`;
}
return fetch(`${this.httpBaseUrl}/${endpoint}`, {
const startTime = new Date();
let response = await fetch(`${this.httpBaseUrl}/${endpoint}`, {
method: "POST",
headers: headers,
body: JSON.stringify(data),
}).then(response => {
return response.json();
signal: controller.signal,
});
const endTime = new Date();
clearTimeout(timer);
let responseData = await response.json();
responseData.duration = endTime - startTime;
return responseData;
}
}
authenticate(accountName, password) {
return this.send("authenticate", {
async ping() {
let result = {"http": null, "ws": null};
const res = await this.send("ping", {}, undefined, true);
result.http = res.duration;
if (this.wsConnection) {
await this.wsConnection.ping();
}
return result;
}
async authenticate(accountName, password) {
let response = await this.send("authenticate", {
type: "password",
name: accountName,
password: password,
}).then(response => {
this.token = response.token;
return response;
});
if (response.status === "success") {
this.token = response.data.token;
}
return response;
}
sendEvent(roomId, data) {
async sendEvent(roomId, data) {
return this.send("send_event", {
room_id: roomId,
data: data,