mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-01 16:26:39 +00:00
Websocket connects
This commit is contained in:
@@ -11,6 +11,13 @@ import { tokenManager } from "./lib/tokenManager";
|
|||||||
import { APP_VERSION } from "./lib/consts";
|
import { APP_VERSION } from "./lib/consts";
|
||||||
|
|
||||||
export async function createHybridClientServer() {
|
export async function createHybridClientServer() {
|
||||||
|
logger.info("Starting hybrid client server...");
|
||||||
|
|
||||||
|
// Start the token manager
|
||||||
|
await tokenManager.start();
|
||||||
|
|
||||||
|
const token = await tokenManager.getToken();
|
||||||
|
|
||||||
const monitor = new TraefikConfigManager();
|
const monitor = new TraefikConfigManager();
|
||||||
|
|
||||||
await monitor.start();
|
await monitor.start();
|
||||||
@@ -23,11 +30,6 @@ export async function createHybridClientServer() {
|
|||||||
throw new Error("Hybrid configuration is not defined");
|
throw new Error("Hybrid configuration is not defined");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the token manager
|
|
||||||
await tokenManager.start();
|
|
||||||
|
|
||||||
const token = await tokenManager.getToken();
|
|
||||||
|
|
||||||
// Create client
|
// Create client
|
||||||
const client = createWebSocketClient(
|
const client = createWebSocketClient(
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -17,11 +17,13 @@ async function startServers() {
|
|||||||
// Start all servers
|
// Start all servers
|
||||||
const apiServer = createApiServer();
|
const apiServer = createApiServer();
|
||||||
const internalServer = createInternalServer();
|
const internalServer = createInternalServer();
|
||||||
const nextServer = await createNextServer();
|
|
||||||
|
|
||||||
let hybridClientServer;
|
let hybridClientServer;
|
||||||
|
let nextServer;
|
||||||
if (config.isHybridMode()) {
|
if (config.isHybridMode()) {
|
||||||
hybridClientServer = createHybridClientServer();
|
hybridClientServer = await createHybridClientServer();
|
||||||
|
} else {
|
||||||
|
nextServer = await createNextServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
let integrationServer;
|
let integrationServer;
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ export class Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public isHybridMode() {
|
public isHybridMode() {
|
||||||
return this.rawConfig?.hybrid;
|
return typeof this.rawConfig?.hybrid === "object";
|
||||||
}
|
}
|
||||||
|
|
||||||
public async checkSupporterKey() {
|
public async checkSupporterKey() {
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ export class TokenManager {
|
|||||||
/**
|
/**
|
||||||
* Get the current valid token
|
* Get the current valid token
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO: WE SHOULD NOT BE GETTING A TOKEN EVERY TIME WE REQUEST IT
|
||||||
async getToken(): Promise<string> {
|
async getToken(): Promise<string> {
|
||||||
if (!this.token) {
|
if (!this.token) {
|
||||||
if (this.isRefreshing) {
|
if (this.isRefreshing) {
|
||||||
|
|||||||
@@ -848,7 +848,7 @@ authRouter.post(
|
|||||||
rateLimit({
|
rateLimit({
|
||||||
windowMs: 15 * 60 * 1000,
|
windowMs: 15 * 60 * 1000,
|
||||||
max: 900,
|
max: 900,
|
||||||
keyGenerator: (req) => `newtGetToken:${req.body.newtId || req.ip}`,
|
keyGenerator: (req) => `olmGetToken:${req.body.newtId || req.ip}`,
|
||||||
handler: (req, res, next) => {
|
handler: (req, res, next) => {
|
||||||
const message = `You can only request an Olm token ${900} times every ${15} minutes. Please try again later.`;
|
const message = `You can only request an Olm token ${900} times every ${15} minutes. Please try again later.`;
|
||||||
return next(createHttpError(HttpCode.TOO_MANY_REQUESTS, message));
|
return next(createHttpError(HttpCode.TOO_MANY_REQUESTS, message));
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ export class WebSocketClient extends EventEmitter {
|
|||||||
private pingTimer: NodeJS.Timeout | null = null;
|
private pingTimer: NodeJS.Timeout | null = null;
|
||||||
private pingTimeoutTimer: NodeJS.Timeout | null = null;
|
private pingTimeoutTimer: NodeJS.Timeout | null = null;
|
||||||
private token: string;
|
private token: string;
|
||||||
|
private isConnecting: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
token: string,
|
token: string,
|
||||||
@@ -46,14 +47,16 @@ export class WebSocketClient extends EventEmitter {
|
|||||||
|
|
||||||
this.token = token;
|
this.token = token;
|
||||||
this.baseURL = options.baseURL || endpoint;
|
this.baseURL = options.baseURL || endpoint;
|
||||||
this.reconnectInterval = options.reconnectInterval || 3000;
|
this.reconnectInterval = options.reconnectInterval || 5000;
|
||||||
this.pingInterval = options.pingInterval || 30000;
|
this.pingInterval = options.pingInterval || 30000;
|
||||||
this.pingTimeout = options.pingTimeout || 10000;
|
this.pingTimeout = options.pingTimeout || 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async connect(): Promise<void> {
|
public async connect(): Promise<void> {
|
||||||
this.shouldReconnect = true;
|
this.shouldReconnect = true;
|
||||||
await this.connectWithRetry();
|
if (!this.isConnecting) {
|
||||||
|
await this.connectWithRetry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async close(): Promise<void> {
|
public async close(): Promise<void> {
|
||||||
@@ -141,20 +144,30 @@ export class WebSocketClient extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async connectWithRetry(): Promise<void> {
|
private async connectWithRetry(): Promise<void> {
|
||||||
while (this.shouldReconnect) {
|
if (this.isConnecting) return;
|
||||||
|
|
||||||
|
this.isConnecting = true;
|
||||||
|
|
||||||
|
while (this.shouldReconnect && !this.isConnected) {
|
||||||
try {
|
try {
|
||||||
await this.establishConnection();
|
await this.establishConnection();
|
||||||
|
this.isConnecting = false;
|
||||||
return;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to connect: ${error}. Retrying in ${this.reconnectInterval}ms...`);
|
console.error(`Failed to connect: ${error}. Retrying in ${this.reconnectInterval}ms...`);
|
||||||
|
|
||||||
if (!this.shouldReconnect) return;
|
if (!this.shouldReconnect) {
|
||||||
|
this.isConnecting = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await new Promise(resolve => {
|
await new Promise(resolve => {
|
||||||
this.reconnectTimer = setTimeout(resolve, this.reconnectInterval);
|
this.reconnectTimer = setTimeout(resolve, this.reconnectInterval);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.isConnecting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async establishConnection(): Promise<void> {
|
private async establishConnection(): Promise<void> {
|
||||||
@@ -174,6 +187,7 @@ export class WebSocketClient extends EventEmitter {
|
|||||||
console.debug('WebSocket connection established');
|
console.debug('WebSocket connection established');
|
||||||
this.conn = conn;
|
this.conn = conn;
|
||||||
this.setConnected(true);
|
this.setConnected(true);
|
||||||
|
this.isConnecting = false;
|
||||||
this.startPingMonitor();
|
this.startPingMonitor();
|
||||||
this.emit('connect');
|
this.emit('connect');
|
||||||
resolve();
|
resolve();
|
||||||
@@ -232,6 +246,7 @@ export class WebSocketClient extends EventEmitter {
|
|||||||
|
|
||||||
private handleDisconnect(): void {
|
private handleDisconnect(): void {
|
||||||
this.setConnected(false);
|
this.setConnected(false);
|
||||||
|
this.isConnecting = false;
|
||||||
|
|
||||||
// Clear ping timers
|
// Clear ping timers
|
||||||
if (this.pingTimer) {
|
if (this.pingTimer) {
|
||||||
@@ -252,7 +267,10 @@ export class WebSocketClient extends EventEmitter {
|
|||||||
|
|
||||||
// Reconnect if needed
|
// Reconnect if needed
|
||||||
if (this.shouldReconnect) {
|
if (this.shouldReconnect) {
|
||||||
this.connectWithRetry();
|
// Add a small delay before starting reconnection to prevent immediate retry
|
||||||
|
setTimeout(() => {
|
||||||
|
this.connectWithRetry();
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user