




















@@ -150,6 +150,7 @@ function buildRealtimeRejectedTwiML(): WebhookResponsePayload {
150150export class VoiceCallWebhookServer {
151151private server: http.Server | null = null;
152152private listeningUrl: string | null = null;
153+private startPromise: Promise<string> | null = null;
153154private config: VoiceCallConfig;
154155private manager: CallManager;
155156private provider: VoiceCallProvider;
@@ -443,7 +444,11 @@ export class VoiceCallWebhookServer {
443444await this.initializeMediaStreaming();
444445}
445446446-return new Promise((resolve, reject) => {
447+if (this.startPromise) {
448+return this.startPromise;
449+}
450+451+this.startPromise = new Promise((resolve, reject) => {
447452this.server = http.createServer((req, res) => {
448453this.handleRequest(req, res, webhookPath).catch((err) => {
449454console.error("[voice-call] Webhook error:", err);
@@ -468,11 +473,17 @@ export class VoiceCallWebhookServer {
468473});
469474}
470475471-this.server.on("error", reject);
476+this.server.on("error", (err) => {
477+this.server = null;
478+this.listeningUrl = null;
479+this.startPromise = null;
480+reject(err);
481+});
472482473483this.server.listen(port, bind, () => {
474484const url = this.resolveListeningUrl(bind, webhookPath);
475485this.listeningUrl = url;
486+this.startPromise = null;
476487console.log(`[voice-call] Webhook server listening on ${url}`);
477488if (this.mediaStreamHandler) {
478489const address = this.server?.address();
@@ -491,6 +502,8 @@ export class VoiceCallWebhookServer {
491502});
492503});
493504});
505+506+return this.startPromise;
494507}
495508496509/**
@@ -502,6 +515,7 @@ export class VoiceCallWebhookServer {
502515}
503516this.pendingDisconnectHangups.clear();
504517this.webhookInFlightLimiter.clear();
518+this.startPromise = null;
505519506520if (this.stopStaleCallReaper) {
507521this.stopStaleCallReaper();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。