主播连线和 PK

AtomicXCore 提供了 CoHostState 核心模块,用于处理跨房连线。本文档将指导您如何组合使用该工具,来完成直播场景下连线的完整流程。

核心场景

一次完整的“主播连线”通常包含两个核心阶段,其整体流程如下:


示例项目

您可参考我们在 GitHub 上提供的 CoHostPanel 组件来查看完整实现。

实现步骤

步骤1:组件集成

请参考 快速接入 集成 AtomicXCore,并完成 LiveCoreView 的接入。
注意:
下列步骤需要参考 快速接入 中先创建房间或加入房间,随后执行下列步骤中的方法。

步骤2:实现跨房连线

此步骤的目标是让两个主播的画面出现在同一个视图中,我们将使用 CoHostState 来完成。

邀请方(主播 A)实现

1. 发起连线邀请
当主播A在界面上选择目标主播 B 并发起连线时,调用 requestHostConnection 方法。
import { useCoHostState, CoHostLayoutTemplate } from "tuikit-atomicx-vue3";

// 获取 CoHostState 实例
const { requestHostConnection } = useCoHostState();

// 用户点击“连线”按钮,并选择了主播 B (targetLiveId)
const inviteHostB = async (targetLiveId: string) => {
try {
await requestHostConnection({
liveId: targetLiveId, // 目标主播 B 的房间 ID
layoutTemplate: CoHostLayoutTemplate.Grid, // 选择一个布局模版
timeout: 30, // 邀请超时时间(秒)
extensionInfo: '', // 可选扩展信息
});
console.log("连线邀请已发送,等待对方处理...");
} catch (error) {
console.error("邀请发送失败", error);
// 可以在这里进行 Toast 提示
}
};
2. 监听邀请结果
通过调用 useCoHostState 提供的 subscribeEvent 方法订阅对应的事件,您可以接收到主播 B 的处理结果。

import { useCoHostState, CoHostEvent } from "tuikit-atomicx-vue3";
import { onMounted, onUnmounted } from 'vue';

const { subscribeEvent, unsubscribeEvent } = useCoHostState();

const onAccepted = (eventInfo: any) => {
console.log(`主播 ${eventInfo.invitee.userName} 同意了您的连线邀请`);
};

const onRejected = (eventInfo: any) => {
console.log(`主播 ${eventInfo.invitee.userName} 拒绝了您的连线邀请`);
};

const onTimeout = (eventInfo: any) => {
console.log('邀请超时,对方未回应');
};

onMounted(() => {
subscribeEvent(CoHostEvent.onCoHostRequestAccepted, onAccepted);
subscribeEvent(CoHostEvent.onCoHostRequestRejected, onRejected);
subscribeEvent(CoHostEvent.onCoHostRequestTimeout, onTimeout);
});

onUnmounted(() => {
unsubscribeEvent(CoHostEvent.onCoHostRequestAccepted, onAccepted);
unsubscribeEvent(CoHostEvent.onCoHostRequestRejected, onRejected);
unsubscribeEvent(CoHostEvent.onCoHostRequestTimeout, onTimeout);
});

受邀方(主播 B)实现

1. 接收连线邀请
通过 subscribeEvent 订阅 onCoHostRequestReceived 事件,主播 B 可以监听到来自主播 A 的邀请。
import { useCoHostState, CoHostEvent } from "tuikit-atomicx-vue3";
import { onMounted, onUnmounted } from 'vue';

const { subscribeEvent, unsubscribeEvent } = useCoHostState();

const onRequestReceived = (eventInfo: any) => {
const { inviter } = eventInfo;
console.log(`收到主播 ${inviter.userName} 的连线邀请`);
// 可以在这里弹出 Dialog 询问用户是否接受
};

onMounted(() => {
subscribeEvent(CoHostEvent.onCoHostRequestReceived, onRequestReceived);
});

onUnmounted(() => {
unsubscribeEvent(CoHostEvent.onCoHostRequestReceived, onRequestReceived);
});
2. 响应连线邀请
当主播 B 在弹出的对话框中做出选择后,调用相应的方法。
import { useCoHostState } from "tuikit-atomicx-vue3";

// 获取 CoHostState 实例
const { acceptHostConnection, rejectHostConnection, applicant } = useCoHostState();

// 接受邀请
const acceptInvitation = async () => {
if (applicant.value) {
try {
// 传入发起方的 liveId (roomId)
await acceptHostConnection({ liveId: applicant.value.liveId });
console.log('已接受连线');
} catch (error) {
console.error('接受连线失败', error);
}
}
};

// 拒绝邀请
const rejectInvitation = async () => {
if (applicant.value) {
try {
await rejectHostConnection({ liveId: applicant.value.liveId });
console.log('已拒绝连线');
} catch (error) {
console.error('拒绝连线失败', error);
}
}
};

步骤3:结束连线

当 PK 进行中,任意一方都可以主动结束连线;同时,我们也需要感知对方离开连线的事件,以恢复单主播直播布局。

1. 主动结束连线

调用 exitHostConnection 方法即可断开当前的跨房连线。此操作对邀请方和受邀方通用。
import { useCoHostState, CoHostStatus } from "tuikit-atomicx-vue3";

// 获取 CoHostState 实例
const { exitHostConnection, coHostStatus } = useCoHostState();

// 点击“结束PK”按钮的处理函数
const stopPK = async () => {
// 判断当前是否处于连线状态
if (coHostStatus.value === CoHostStatus.Connected) {
try {
await exitHostConnection();
console.log('已退出连线');
// 在此处执行 UI 布局重置等业务逻辑
} catch (error) {
console.error('退出连线失败:', error);
}
}
};

2. 监听对方离开

当对方主动断开或因异常掉线时,我们需要通过订阅 onCoHostUserLeft 事件来感知,并更新本地 UI。
import { useCoHostState, CoHostEvent } from "tuikit-atomicx-vue3";
import { onMounted, onUnmounted } from 'vue';

const { subscribeEvent, unsubscribeEvent } = useCoHostState();

const onUserLeft = (eventInfo: any) => {
const { userInfo } = eventInfo;
console.log(`主播 ${userInfo.userName} 已断开连线`);
// 在此处恢复单主播布局,清除对方画面
};

onMounted(() => {
// 订阅用户离开事件
subscribeEvent(CoHostEvent.onCoHostUserLeft, onUserLeft);
});

onUnmounted(() => {
unsubscribeEvent(CoHostEvent.onCoHostUserLeft, onUserLeft);
});

运行效果

当您集成以上功能实现后,请分别使用主播 A 和主播 B 进行对应操作,运行效果如下。


API 文档

关于 CoHostState 及其相关类的所有公开接口、属性和方法的详细信息,请您参阅 AtomicXCore 框架的官方 API 文档。本指南使用到的相关 State 如下:
State
功能描述
API 文档
DeviceState
音视频设备控制:麦克风(开关 / 音量)、摄像头(开关 / 切换 / 画质)、屏幕共享,设备状态实时监听。
CoHostState
主播跨房连线:支持多布局模板(动态网格等),发起 / 接受 / 拒绝连线,连麦主播互动管理。

常见问题

为什么发起连线邀请后,对方(主播 B)没有收到回调?

如果在调用 requestHostConnection 后,受邀方未触发 onCoHostRequestReceived 事件,请依次排查以下情况:
参数校验: 确保传入的 liveId 是目标主播的真实房间 ID,而非用户 ID 或其他业务 ID。
事件订阅: 受邀方必须在组件挂载(onMounted)时调用 subscribeEvent 订阅 CoHostEvent.onCoHostRequestReceived 事件,否则无法接收通知。

为什么 candidates(可邀请列表)中找不到我想邀请的主播?

candidates 是一个计算属性(Computed Ref),它会自动过滤掉不符合邀请条件的用户。如果列表中没有目标用户,可能是因为:
已过滤: 该用户已经是当前连麦中 (connected)、已发出邀请 (invitees) 或正在申请中 (applicant) 的状态。
排除自己: 列表会自动排除当前登录用户自己。
列表未更新: 确保 liveList 已正确获取。您可以手动调用 fetchLiveList 刷新。

如何处理连线邀请“超时”的情况?

在调用 requestHostConnection 时可以传入 timeout 参数(单位:秒)。
发起方: 如果超时时间内未收到响应,SDK 会自动清理邀请列表中的该用户,并触发 CoHostEvent.onCoHostRequestTimeout 事件。
受邀方: 如果超时未处理,也会触发相同的超时事件,且 applicant 状态会被重置。
建议: 双方都应监听 onCoHostRequestTimeout 事件以更新 UI(例如关闭等待弹窗)。

接受连线(acceptHostConnection)失败了怎么办?

接受连线可能会因为网络波动或房间状态变更而失败。
捕获错误: 请务必使用 try...catch 包裹 acceptHostConnection 调用。
状态检查: 在调用前,建议再次检查 applicant.value 是否存在且 liveId 有效,防止因超时或对方取消导致的状态不一致。