Add basic ws client

This commit is contained in:
Owen 2025-08-12 14:30:23 -07:00
parent 15f900317a
commit b6c2f123e8
No known key found for this signature in database
GPG key ID: 8271FDFFD9E0CCBD
3 changed files with 91 additions and 2 deletions

View file

@ -0,0 +1,76 @@
import next from "next";
import express from "express";
import { parse } from "url";
import logger from "@server/logger";
import config from "@server/lib/config";
import { WebSocketClient, createWebSocketClient } from "./routers/ws/client";
import { addPeer, deletePeer } from "./routers/gerbil/peers";
import { db, exitNodes } from "./db";
export async function createHybridClientServer() {
if (
!config.getRawConfig().hybrid?.id ||
!config.getRawConfig().hybrid?.secret ||
!config.getRawConfig().hybrid?.endpoint
) {
throw new Error("Hybrid configuration is not defined");
}
// Create client
const client = createWebSocketClient(
"remoteExitNode", // or 'olm'
config.getRawConfig().hybrid!.id!,
config.getRawConfig().hybrid!.secret!,
config.getRawConfig().hybrid!.endpoint!,
{
reconnectInterval: 5000,
pingInterval: 30000,
pingTimeout: 10000
}
);
// Register message handlers
client.registerHandler("remote/peers/add", async (message) => {
const { pubKey, allowedIps } = message.data;
// TODO: we are getting the exit node twice here
// NOTE: there should only be one gerbil registered so...
const [exitNode] = await db.select().from(exitNodes).limit(1);
await addPeer(exitNode.exitNodeId, {
publicKey: pubKey,
allowedIps: allowedIps || []
});
});
client.registerHandler("remote/peers/remove", async (message) => {
const { pubKey } = message.data;
// TODO: we are getting the exit node twice here
// NOTE: there should only be one gerbil registered so...
const [exitNode] = await db.select().from(exitNodes).limit(1);
await deletePeer(exitNode.exitNodeId, pubKey);
});
// Listen to connection events
client.on("connect", () => {
console.log("Connected to WebSocket server");
});
client.on("disconnect", () => {
console.log("Disconnected from WebSocket server");
});
client.on("message", (message) => {
console.log("Received message:", message.type, message.data);
});
// Connect to the server
try {
await client.connect();
console.log("Connection initiated");
} catch (error) {
console.error("Failed to connect:", error);
}
client.sendMessageInterval("heartbeat", { timestamp: Date.now() }, 10000);
}

View file

@ -7,6 +7,7 @@ import { createNextServer } from "./nextServer";
import { createInternalServer } from "./internalServer";
import { ApiKey, ApiKeyOrg, Session, User, UserOrg } from "@server/db";
import { createIntegrationApiServer } from "./integrationApiServer";
import { createHybridClientServer } from "./hybridClientServer";
import config from "@server/lib/config";
async function startServers() {
@ -18,6 +19,11 @@ async function startServers() {
const internalServer = createInternalServer();
const nextServer = await createNextServer();
let hybridClientServer;
if (config.getRawConfig().hybrid) {
hybridClientServer = createHybridClientServer();
}
let integrationServer;
if (config.getRawConfig().flags?.enable_integration_api) {
integrationServer = createIntegrationApiServer();
@ -27,7 +33,8 @@ async function startServers() {
apiServer,
nextServer,
internalServer,
integrationServer
integrationServer,
hybridClientServer
};
}

View file

@ -4,6 +4,7 @@ import { configFilePath1, configFilePath2 } from "./consts";
import { z } from "zod";
import stoi from "./stoi";
import { build } from "@server/build";
import { setAdminCredentials } from "@cli/commands/setAdminCredentials";
const portSchema = z.number().positive().gt(0).lte(65535);
@ -25,8 +26,13 @@ export const configSchema = z
.optional()
.default("info"),
save_logs: z.boolean().optional().default(false),
log_failed_attempts: z.boolean().optional().default(false)
log_failed_attempts: z.boolean().optional().default(false),
}),
hybrid: z.object({
id: z.string().optional(),
secret: z.string().optional(),
endpoint: z.string().optional()
}).optional(),
domains: z
.record(
z.string(),