feat(streamer): pcm tcp tap with reconnect backoff

This commit is contained in:
devilreef 2026-04-30 15:21:32 +06:00
parent 8bca1767bd
commit 40ac86717a
Signed by: devilreef
SSH key fingerprint: SHA256:UZisRr4iuXx+IhkbZnR655L2RWAT6o2rgbGv5F/6m3Y

51
streamer/src/pcm-tap.ts Normal file
View file

@ -0,0 +1,51 @@
import { EventEmitter } from "node:events";
import { Socket, connect } from "node:net";
export interface PcmTapOpts {
host: string;
port: number;
reconnectInitialMs?: number;
reconnectMaxMs?: number;
}
export class PcmTap extends EventEmitter {
private socket: Socket | null = null;
private stopped = false;
private backoff: number;
constructor(private opts: PcmTapOpts) {
super();
this.backoff = opts.reconnectInitialMs ?? 1000;
}
start(): void {
if (this.stopped) return;
this.connect();
}
stop(): void {
this.stopped = true;
this.socket?.destroy();
}
private connect(): void {
this.emit("connecting");
const sock = connect({ host: this.opts.host, port: this.opts.port });
this.socket = sock;
sock.on("connect", () => {
this.emit("connected");
this.backoff = this.opts.reconnectInitialMs ?? 1000;
});
sock.on("data", (chunk) => this.emit("data", chunk));
sock.on("error", (err) => this.emit("warn", err));
sock.on("close", () => {
if (this.stopped) return;
this.emit("disconnected");
const max = this.opts.reconnectMaxMs ?? 30000;
const wait = Math.min(this.backoff, max);
this.backoff = Math.min(this.backoff * 2, max);
setTimeout(() => this.connect(), wait);
});
}
}