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

NextJS集成GetStream Video SDK时被叫方无来电状态问题

GetStream Video SDK 被叫方无法接收通话通知的问题排查与修复

一、被叫方代码核心问题修复

1. 补全必要认证信息

原代码中userId、apiKey、token均为空,这会直接导致无法连接GetStream服务,自然收不到通话事件。必须填入对应被叫用户(Pre_Vizsla)的有效token、userId,以及和主叫方一致的apiKey。

2. 规范Client实例与事件监听

组件每次渲染都会创建新的StreamVideoClient,且未清理监听事件,会导致监听失效或重复绑定。用useMemo缓存Client实例,useEffect管理监听生命周期:

import {
  Call,
  RingingCall,
  StreamCall,
  StreamVideo,
  StreamVideoClient,
} from '@stream-io/video-react-sdk';
import {useState, useEffect, useMemo} from 'react';

// 填入正确的认证信息
const apiKey = 'mmhfdzb5evj2';
const userId = 'Pre_Vizsla';
const token = '此处替换为Pre_Vizsla的有效token';
const user = {
  id: userId,
  name: 'Pre Vizsla',
  image: 'https://getstream.io/random_svg/?id=pre-vizsla&name=Pre+Vizsla',
};

const RingingLayout = () => {
  const [call, setCall] = useState<Call>();
  // 缓存Client实例,避免重复创建
  const client = useMemo(() => new StreamVideoClient({apiKey, user, token}), []);

  useEffect(() => {
    const handleIncomingCall = async (incomingCall) => {
      console.log('收到来电:', incomingCall);
      // 可选择自动接听或等待用户操作
      // await incomingCall.answer();
      setCall(incomingCall);
    };
    client.on('incomingCall', handleIncomingCall);

    // 组件卸载时移除监听
    return () => {
      client.off('incomingCall', handleIncomingCall);
    };
  }, [client]);

  return (
    <StreamVideo client={client}>
      {call ? (
        <StreamCall call={call}>
          <RingingCall />
        </StreamCall>
      ) : (
        <div>等待来电...</div>
      )}
    </StreamVideo>
  );
};

export default RingingLayout;

3. 修复初始渲染逻辑

原代码if (!call) return null会导致StreamVideo Provider未挂载,影响事件监听。改为渲染等待UI,确保Provider始终生效。

二、主叫方代码优化

1. 缓存Client实例

避免每次渲染重新创建Client:

const client = useMemo(() => new StreamVideoClient({apiKey, user, token}), [user]);

2. 修复UILayout组件逻辑

原组件中useEffect返回JSX不符合React规则,且缺少client、call props,修改后:

export const UILayout = ({handleLeave, call, client}) => {
  const {useCallState} = useCallStateHooks();
  const callingState = useCallState();

  if (callingState !== CallingState.JOINED) {
    return <div>Loading...</div>;
  }

  return (
    <CustomStackFullWidth>
      <StreamVideo client={client}>
        <StreamCall call={call}>
          <button onClick={handleLeave}>挂断通话</button>
          {/* 补充其他通话UI组件 */}
        </StreamCall>
      </StreamVideo>
    </CustomStackFullWidth>
  );
};

渲染时传入对应props:

<UILayout handleLeave={handleLeave} call={call} client={client} />

3. 规范通话创建流程

改用创建+邀请的方式,确保被叫方收到通知:

const handleCreateCall = async () => {
  const newCall = client.call('default', callId);
  await newCall.join({ring: true});
  // 明确邀请目标成员
  await newCall.invite([{user_id: 'Pre_Vizsla'}]);
  setCall(newCall);
};

三、通用排查要点

  • 确认主被叫的apiKey一致,各自token对应用户ID正确且未过期。
  • 检查GetStream控制台中,应用已开启视频通话功能,目标用户已存在。
  • 查看浏览器控制台的错误日志,排查认证失败、连接异常等问题。

内容的提问来源于stack exchange,提问作者Anwar Hossain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:59:52