mirror of
https://github.com/fosrl/pangolin.git
synced 2026-01-29 06:10:47 +00:00
Fix ws reconnect and change create site
This commit is contained in:
@@ -139,9 +139,13 @@ export async function createHybridClientServer() {
|
||||
logger.error("Failed to connect:", error);
|
||||
}
|
||||
|
||||
client.sendMessageInterval(
|
||||
// Store the ping interval stop function for cleanup if needed
|
||||
const stopPingInterval = client.sendMessageInterval(
|
||||
"remoteExitNode/ping",
|
||||
{ timestamp: Date.now() / 1000 },
|
||||
60000
|
||||
); // send every minute
|
||||
|
||||
// Return client and cleanup function for potential use
|
||||
return { client, stopPingInterval };
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ export async function createSite(
|
||||
await db.transaction(async (trx) => {
|
||||
let newSite: Site;
|
||||
|
||||
if (exitNodeId) {
|
||||
if ((type == "wireguard" || type == "newt") && exitNodeId) {
|
||||
// we are creating a site with an exit node (tunneled)
|
||||
if (!subnet) {
|
||||
return next(
|
||||
@@ -264,12 +264,14 @@ export async function createSite(
|
||||
[newSite] = await trx
|
||||
.insert(sites)
|
||||
.values({
|
||||
exitNodeId: exitNodeId,
|
||||
orgId,
|
||||
name,
|
||||
niceId,
|
||||
address: updatedAddress || null,
|
||||
type,
|
||||
dockerSocketEnabled: type == "newt",
|
||||
dockerSocketEnabled: false,
|
||||
online: true,
|
||||
subnet: "0.0.0.0/0"
|
||||
})
|
||||
.returning();
|
||||
|
||||
@@ -145,11 +145,11 @@ export class WebSocketClient extends EventEmitter {
|
||||
}
|
||||
|
||||
private async connectWithRetry(): Promise<void> {
|
||||
if (this.isConnecting) return;
|
||||
if (this.isConnecting || this.isConnected) return;
|
||||
|
||||
this.isConnecting = true;
|
||||
|
||||
while (this.shouldReconnect && !this.isConnected) {
|
||||
while (this.shouldReconnect && !this.isConnected && this.isConnecting) {
|
||||
try {
|
||||
await this.establishConnection();
|
||||
this.isConnecting = false;
|
||||
@@ -157,7 +157,7 @@ export class WebSocketClient extends EventEmitter {
|
||||
} catch (error) {
|
||||
logger.error(`Failed to connect: ${error}. Retrying in ${this.reconnectInterval}ms...`);
|
||||
|
||||
if (!this.shouldReconnect) {
|
||||
if (!this.shouldReconnect || !this.isConnecting) {
|
||||
this.isConnecting = false;
|
||||
return;
|
||||
}
|
||||
@@ -172,6 +172,13 @@ export class WebSocketClient extends EventEmitter {
|
||||
}
|
||||
|
||||
private async establishConnection(): Promise<void> {
|
||||
// Clean up any existing connection before establishing a new one
|
||||
if (this.conn) {
|
||||
this.conn.removeAllListeners();
|
||||
this.conn.close();
|
||||
this.conn = null;
|
||||
}
|
||||
|
||||
// Parse the base URL to determine protocol and hostname
|
||||
const baseURL = new URL(this.baseURL);
|
||||
const wsProtocol = baseURL.protocol === 'https:' ? 'wss' : 'ws';
|
||||
@@ -217,9 +224,8 @@ export class WebSocketClient extends EventEmitter {
|
||||
if (this.conn === null) {
|
||||
// Connection failed during establishment
|
||||
reject(error);
|
||||
} else {
|
||||
this.handleDisconnect();
|
||||
}
|
||||
// Don't call handleDisconnect here as the 'close' event will handle it
|
||||
});
|
||||
|
||||
conn.on('pong', () => {
|
||||
@@ -232,6 +238,12 @@ export class WebSocketClient extends EventEmitter {
|
||||
}
|
||||
|
||||
private startPingMonitor(): void {
|
||||
// Clear any existing ping timer to prevent duplicates
|
||||
if (this.pingTimer) {
|
||||
clearInterval(this.pingTimer);
|
||||
this.pingTimer = null;
|
||||
}
|
||||
|
||||
this.pingTimer = setInterval(() => {
|
||||
if (this.conn && this.conn.readyState === WebSocket.OPEN) {
|
||||
this.conn.ping();
|
||||
@@ -246,6 +258,11 @@ export class WebSocketClient extends EventEmitter {
|
||||
}
|
||||
|
||||
private handleDisconnect(): void {
|
||||
// Prevent multiple disconnect handlers from running simultaneously
|
||||
if (!this.isConnected && !this.isConnecting) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setConnected(false);
|
||||
this.isConnecting = false;
|
||||
|
||||
@@ -259,6 +276,12 @@ export class WebSocketClient extends EventEmitter {
|
||||
this.pingTimeoutTimer = null;
|
||||
}
|
||||
|
||||
// Clear any existing reconnect timer to prevent multiple reconnection attempts
|
||||
if (this.reconnectTimer) {
|
||||
clearTimeout(this.reconnectTimer);
|
||||
this.reconnectTimer = null;
|
||||
}
|
||||
|
||||
if (this.conn) {
|
||||
this.conn.removeAllListeners();
|
||||
this.conn = null;
|
||||
@@ -269,7 +292,7 @@ export class WebSocketClient extends EventEmitter {
|
||||
// Reconnect if needed
|
||||
if (this.shouldReconnect) {
|
||||
// Add a small delay before starting reconnection to prevent immediate retry
|
||||
setTimeout(() => {
|
||||
this.reconnectTimer = setTimeout(() => {
|
||||
this.connectWithRetry();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ export default function SiteInfoCard({}: SiteInfoCardProps) {
|
||||
</InfoSectionContent>
|
||||
</InfoSection>
|
||||
|
||||
{env.flags.enableClients && (
|
||||
{env.flags.enableClients && site.type == "newt" && (
|
||||
<InfoSection>
|
||||
<InfoSectionTitle>Address</InfoSectionTitle>
|
||||
<InfoSectionContent>
|
||||
|
||||
Reference in New Issue
Block a user