You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中使用Deepgram SDK时,如何重新连接已关闭的Socket?

Deepgram Live SDK 连接超时断开&重新连接后无法接收转录数据问题解决

问题根源分析

当前代码存在几个核心问题导致连接超时和重新连接失效:

  • 全局变量liveClient:跨组件或组件重新渲染时会复用旧实例,事件监听重复绑定,状态混乱
  • keepAlive()单次调用:该方法需要定时发送心跳包才能维持连接,单次调用无法阻止12秒超时
  • 缺乏实例清理机制:重新连接时未销毁旧实例,新实例的事件监听未正确绑定,导致无法接收转录数据

修复方案

1. 将liveClient转为组件状态

用useState存储客户端实例,避免全局变量带来的状态污染,确保每次重新连接都创建全新实例。

2. 定时发送心跳包

在连接建立后启动定时器,每10秒调用一次keepAlive(),确保在12秒超时前维持连接。

3. 新增手动连接函数

提供明确的connect方法,用于重新连接时销毁旧实例、创建新实例并绑定所有事件监听。

4. 完善清理机制

在组件卸载或连接关闭时,清理定时器、销毁客户端实例,避免内存泄漏。

修改后的完整代码

import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react';
import { LiveClient, LiveTranscriptionEvent, LiveTranscriptionEvents, createClient } from '@deepgram/sdk';

const deepgram = createClient(process.env.NEXT_PUBLIC_DEEPGRAM_API_KEY || '');

function useDeepgram(setInputText: Dispatch<SetStateAction<string>>) {
  const [connectionStatus, setConnectionStatus] = useState<'open' | 'closed'>('closed');
  const [liveClient, setLiveClient] = useState<LiveClient | null>(null);
  const [heartbeatTimer, setHeartbeatTimer] = useState<NodeJS.Timeout | null>(null);

  // 绑定事件监听的通用函数
  const bindClientEvents = useCallback((client: LiveClient) => {
    client.on(LiveTranscriptionEvents.Open, () => {
      setConnectionStatus('open');
      // 启动心跳定时器,每10秒发送一次
      const timer = setInterval(() => {
        client.keepAlive();
      }, 10000);
      setHeartbeatTimer(timer);
    });

    client.on(LiveTranscriptionEvents.Transcript, (data: LiveTranscriptionEvent) => {
      if (data.type === 'Results' && data.channel.alternatives[0].transcript) {
        setInputText((prev) => `${prev} ${data.channel.alternatives[0].transcript}`);
      }
    });

    client.on(LiveTranscriptionEvents.Close, () => {
      setConnectionStatus('closed');
      if (heartbeatTimer) clearInterval(heartbeatTimer);
      setHeartbeatTimer(null);
    });

    // 新增错误监听,便于排查问题
    client.on(LiveTranscriptionEvents.Error, (error) => {
      console.error('Deepgram连接错误:', error);
      setConnectionStatus('closed');
    });
  }, [setInputText, heartbeatTimer]);

  // 初始化/重新连接函数
  const connect = useCallback(() => {
    // 销毁旧实例
    if (liveClient) {
      liveClient.finish();
    }
    // 创建新实例
    const newClient = deepgram.listen.live({ model: 'nova' });
    setLiveClient(newClient);
    bindClientEvents(newClient);
  }, [liveClient, bindClientEvents]);

  // 组件挂载时自动连接
  useEffect(() => {
    connect();
    // 组件卸载时清理
    return () => {
      if (liveClient) liveClient.finish();
      if (heartbeatTimer) clearInterval(heartbeatTimer);
    };
  }, []);

  const disconnect = useCallback(() => {
    setConnectionStatus('closed');
    if (liveClient) liveClient.finish();
    if (heartbeatTimer) clearInterval(heartbeatTimer);
    setHeartbeatTimer(null);
  }, [liveClient, heartbeatTimer]);

  const sendData = useCallback(
    (chunk: Blob) => {
      if (liveClient && connectionStatus === 'open') {
        liveClient.send(chunk);
      }
    },
    [liveClient, connectionStatus]
  );

  return { connectionStatus, sendData, disconnect, connect };
}

export default useDeepgram;

关键修改说明

  • 状态管理:用useState管理liveClient和heartbeatTimer,确保状态可控
  • 心跳机制:每10秒发送一次心跳包,避免12秒超时断开
  • 实例清理:重新连接前销毁旧实例,避免资源占用和事件冲突
  • 错误监听:新增Error事件监听,便于排查连接异常问题
  • 手动连接:暴露connect方法,可通过按钮点击触发重新连接,确保新实例正确绑定事件

内容的提问来源于stack exchange,提问作者Balaji Sivasakthi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 04:53:12