WebSockets working
This commit is contained in:
149
src/usimp.ts
149
src/usimp.ts
@ -162,20 +162,23 @@ export class Session {
|
|||||||
const host = this.server.host;
|
const host = this.server.host;
|
||||||
const protocols = this.server.protocols;
|
const protocols = this.server.protocols;
|
||||||
|
|
||||||
/*
|
if ("wss" in protocols) {
|
||||||
if ("ws" in protocols) {
|
this.websocket = new WebSocket(`wss://${host}:${protocols.wss}/_usimp/websocket`, ["usimp"]);
|
||||||
this.websocket = new WebSocket(`ws://${host}:${protocols.ws}/_usimp/websocket`, ["usimp"]);
|
this.websocket.addEventListener("error", (error) => {
|
||||||
|
console.error(error);
|
||||||
|
this.websocket = null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO http -> https
|
if ("https" in protocols) {
|
||||||
if (protocols) {
|
this.httpBaseUrl = `https://${host}:${protocols.https}/_usimp`;
|
||||||
this.httpBaseUrl = `http://${host}:${protocols.http}/_usimp`;
|
|
||||||
try {
|
try {
|
||||||
return await this.ping();
|
return await this.ping();
|
||||||
} catch {
|
} catch {
|
||||||
this.domain.invalidServers.push(this.server);
|
if (this.server !== null) {
|
||||||
this.server = null;
|
this.domain.invalidServers.push(this.server);
|
||||||
|
this.server = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Domain server ${this.server} does not support 'https' transport protocol`);
|
console.warn(`Domain server ${this.server} does not support 'https' transport protocol`);
|
||||||
@ -186,39 +189,111 @@ export class Session {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waitForWebSocket() {
|
||||||
|
if (this.websocket === null) throw Error("websocket not initialized");
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
if (this.websocket?.readyState === this.websocket?.OPEN) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
const handlerOpen = () => {
|
||||||
|
this.websocket?.removeEventListener("open", handlerOpen);
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
const handlerError = (error: any) => {
|
||||||
|
this.websocket?.removeEventListener("error", handlerError);
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
this.websocket?.addEventListener("open", handlerOpen);
|
||||||
|
this.websocket?.addEventListener("error", handlerError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForWebSocketResponse(req_nr: number, timeout: number) {
|
||||||
|
if (this.websocket === null) throw Error("websocket not initialized");
|
||||||
|
return new Promise<any>((resolve, reject) => {
|
||||||
|
const handlerMsg = (msg: any) => {
|
||||||
|
const data = JSON.parse(msg.data);
|
||||||
|
if (data['request_nr'] === req_nr) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
this.websocket?.removeEventListener("message", handlerMsg);
|
||||||
|
this.websocket?.removeEventListener("error", handlerError);
|
||||||
|
resolve(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const handlerError = (error: any) => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
this.websocket?.removeEventListener("message", handlerMsg);
|
||||||
|
this.websocket?.removeEventListener("error", handlerError);
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
const handlerTimeout = () => {
|
||||||
|
this.websocket?.removeEventListener("message", handlerMsg);
|
||||||
|
this.websocket?.removeEventListener("error", handlerError);
|
||||||
|
reject(Error("timeout"));
|
||||||
|
}
|
||||||
|
const timer = setTimeout(handlerTimeout, timeout);
|
||||||
|
this.websocket?.addEventListener("message", handlerMsg);
|
||||||
|
this.websocket?.addEventListener("error", handlerError);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async send(endpoint: string, data: object, timeout: number = 2000, forceHttp: boolean = false) {
|
async send(endpoint: string, data: object, timeout: number = 2000, forceHttp: boolean = false) {
|
||||||
this.numRequests++;
|
this.numRequests++;
|
||||||
|
|
||||||
if (!forceHttp && this.websocket) {
|
while (true) {
|
||||||
this.websocket.send(JSON.stringify({
|
try {
|
||||||
'request_num': this.numRequests,
|
if (!forceHttp && this.websocket) {
|
||||||
'data': data
|
const req_nr = this.numRequests;
|
||||||
}));
|
const response = this.waitForWebSocketResponse(req_nr, timeout);
|
||||||
} else {
|
|
||||||
const controller = new AbortController();
|
|
||||||
const timer = setTimeout(() => controller.abort(), timeout);
|
|
||||||
|
|
||||||
let headers: Record<string, string> = {
|
const startTime = performance.now();
|
||||||
'Content-Type': 'application/json',
|
await this.waitForWebSocket();
|
||||||
'To-Domain': this.domain.id,
|
await this.websocket.send(JSON.stringify({
|
||||||
};
|
'request_nr': req_nr,
|
||||||
if (this.token) {
|
'endpoint': endpoint,
|
||||||
headers['Authorization'] = `usimp ${this.token}`;
|
'to_domain': this.domain.id,
|
||||||
|
'data': data
|
||||||
|
}));
|
||||||
|
const responseData = await response;
|
||||||
|
|
||||||
|
const endTime = performance.now();
|
||||||
|
responseData.duration = endTime - startTime;
|
||||||
|
return responseData;
|
||||||
|
} else {
|
||||||
|
const controller = new AbortController();
|
||||||
|
const timer = setTimeout(() => controller.abort(), timeout);
|
||||||
|
|
||||||
|
let headers: Record<string, string> = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'To-Domain': this.domain.id,
|
||||||
|
};
|
||||||
|
if (this.token) {
|
||||||
|
headers['Authorization'] = `usimp ${this.token}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startTime = performance.now();
|
||||||
|
const response = await fetch(`${this.httpBaseUrl}/${endpoint}`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: headers,
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
signal: controller.signal,
|
||||||
|
});
|
||||||
|
clearTimeout(timer);
|
||||||
|
const responseData = await response.json();
|
||||||
|
|
||||||
|
const endTime = performance.now();
|
||||||
|
responseData.duration = endTime - startTime;
|
||||||
|
return responseData;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
if (this.server !== null) {
|
||||||
|
this.domain.invalidServers.push(this.server);
|
||||||
|
this.server = null;
|
||||||
|
}
|
||||||
|
await this.chooseDomainServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
const startTime = new Date();
|
|
||||||
const response = await fetch(`${this.httpBaseUrl}/${endpoint}`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: headers,
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
signal: controller.signal,
|
|
||||||
});
|
|
||||||
const endTime = new Date();
|
|
||||||
clearTimeout(timer);
|
|
||||||
|
|
||||||
const responseData = await response.json();
|
|
||||||
responseData.duration = endTime.getUTCMilliseconds() - startTime.getUTCMilliseconds();
|
|
||||||
return responseData;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,17 +19,17 @@ Distributed, end-to-end encrypted instant messaging."/>
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<link rel="icon" sizes="64x64" href="/favicon.ico" type="image/x-icon"/>
|
<link rel="icon" sizes="64x64" href="/favicon.ico" type="image/x-icon"/>
|
||||||
<link rel="stylesheet" href="/res/styles/styles.css?v=0.0.0+93" type="text/css"/>
|
|
||||||
<script type="module" src="/res/scripts/usimp.js?v=0.0.0+93"></script>
|
|
||||||
<script type="module" src="/res/scripts/locutus.js?v=0.0.0+93"></script>
|
|
||||||
<script type="module" src="/res/scripts/main.js?v=0.0.0+93"></script>
|
|
||||||
<meta http-equiv="Content-Security-Policy" content="
|
<meta http-equiv="Content-Security-Policy" content="
|
||||||
default-src 'none';
|
default-src 'none';
|
||||||
style-src 'unsafe-inline';
|
style-src 'unsafe-inline' 'self';
|
||||||
script-src 'self';
|
script-src 'self';
|
||||||
img-src * blob: data:;
|
img-src * blob: data:;
|
||||||
connect-src *;
|
connect-src *;
|
||||||
media-src * blob: data:;"/>
|
media-src * blob: data:;"/>
|
||||||
|
<link rel="stylesheet" href="/res/styles/styles.css?v=0.0.0+123" type="text/css"/>
|
||||||
|
<script type="module" src="/res/scripts/usimp.js?v=0.0.0+123"></script>
|
||||||
|
<script type="module" src="/res/scripts/locutus.js?v=0.0.0+123"></script>
|
||||||
|
<script type="module" src="/res/scripts/main.js?v=0.0.0+123"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
|
Reference in New Issue
Block a user