浏览 SDKs · WASM
SDKsWASM商业版

处理通话事件

集中监听 WASM SDK 的通话邀请、参与者和媒体流事件。

复制

通话状态层集中监听邀请生命周期、参与者连接状态和媒体流变化。大多数事件的房间 ID 位于 data.invitation.roomID,媒体流事件则直接提供 data.roomID。参与者进出事件在 invitation 为空时可能只提供 groupID,此时应先从当前群通话状态中查找房间;仍无法确定时,再按群组查询当前房间并更新本地状态。

事件数据

事件data 类型定位和处理所需字段
OnReceiveNewInvitationSignalingInvitationEventinvitation.roomIDinvitation.groupIDparticipantuserID
OnInviteeAcceptedSignalingActionEventinvitation.roomIDuserIDparticipantopUserPlatformID
OnInviteeRejectedSignalingActionEventinvitation.roomIDuserIDopUserPlatformID
OnInvitationCancelledSignalingInvitationEventinvitation.roomIDuserID
OnInvitationTimeoutSignalingInvitationEventinvitation.roomIDuserID
OnInviteeAcceptedByOtherDeviceSignalingActionEventinvitation.roomIDuserIDopUserPlatformID
OnInviteeRejectedByOtherDeviceSignalingActionEventinvitation.roomIDuserIDopUserPlatformID
OnHangUpSignalingHungUpEventinvitation.roomIDuserID
OnRoomParticipantConnectedSignalingRoomParticipantChangedEventinvitation?.roomIDgroupIDparticipant
OnRoomParticipantDisconnectedSignalingRoomParticipantChangedEventinvitation?.roomIDgroupIDparticipant
OnStreamChangeSignalingStreamChangeEvent直接使用 roomID,并读取 streamTypemute

邀请类事件的 data 不是 SignalingInvitation 本身;应从 data.invitation 读取邀请。参与者列表中的每个用户使用 participant.userInfo.userID 标识,并与 roomID 组合成参与者状态主键。

import { SdkEvent } from '@openim/wasm-client-sdk';

function getCallRoomID(data) {
  return (
    data.roomID ??
    data.invitation?.roomID ??
    (data.groupID ? getActiveRoomIDByGroupID(data.groupID) : undefined)
  );
}

function mergeParticipantEvent(data, action) {
  const roomID = getCallRoomID(data);

  if (!roomID) {
    refreshGroupCall(data.groupID);
    return;
  }

  action(roomID, data.participant ?? []);
}

const handlers = {
  invitation: ({ data }) =>
    upsertCall({
      roomID: data.invitation.roomID,
      invitation: data.invitation,
      participant: data.participant,
      state: 'ringing',
    }),
  accepted: ({ data }) =>
    mergeCallEvent(data.invitation.roomID, 'accepted', data),
  rejected: ({ data }) =>
    mergeCallEvent(data.invitation.roomID, 'rejected', data),
  cancelled: ({ data }) =>
    mergeCallEvent(data.invitation.roomID, 'cancelled', data),
  timeout: ({ data }) =>
    mergeCallEvent(data.invitation.roomID, 'timeout', data),
  acceptedByOtherDevice: ({ data }) =>
    mergeCallEvent(data.invitation.roomID, 'accepted-by-other-device', data),
  rejectedByOtherDevice: ({ data }) =>
    mergeCallEvent(data.invitation.roomID, 'rejected-by-other-device', data),
  hangUp: ({ data }) => finishCall(data.invitation.roomID, data.userID),
  participantConnected: ({ data }) =>
    mergeParticipantEvent(data, addParticipants),
  participantDisconnected: ({ data }) =>
    mergeParticipantEvent(data, removeParticipants),
  streamChanged: ({ data }) => updateRoomStream(data.roomID, data),
};

openimsdk.on(SdkEvent.OnReceiveNewInvitation, handlers.invitation);
openimsdk.on(SdkEvent.OnInviteeAccepted, handlers.accepted);
openimsdk.on(SdkEvent.OnInviteeRejected, handlers.rejected);
openimsdk.on(SdkEvent.OnInvitationCancelled, handlers.cancelled);
openimsdk.on(SdkEvent.OnInvitationTimeout, handlers.timeout);
openimsdk.on(SdkEvent.OnInviteeAcceptedByOtherDevice, handlers.acceptedByOtherDevice);
openimsdk.on(SdkEvent.OnInviteeRejectedByOtherDevice, handlers.rejectedByOtherDevice);
openimsdk.on(SdkEvent.OnHangUp, handlers.hangUp);
openimsdk.on(SdkEvent.OnRoomParticipantConnected, handlers.participantConnected);
openimsdk.on(SdkEvent.OnRoomParticipantDisconnected, handlers.participantDisconnected);
openimsdk.on(SdkEvent.OnStreamChange, handlers.streamChanged);

function removeCallListeners() {
  openimsdk.off(SdkEvent.OnReceiveNewInvitation, handlers.invitation);
  openimsdk.off(SdkEvent.OnInviteeAccepted, handlers.accepted);
  openimsdk.off(SdkEvent.OnInviteeRejected, handlers.rejected);
  openimsdk.off(SdkEvent.OnInvitationCancelled, handlers.cancelled);
  openimsdk.off(SdkEvent.OnInvitationTimeout, handlers.timeout);
  openimsdk.off(SdkEvent.OnInviteeAcceptedByOtherDevice, handlers.acceptedByOtherDevice);
  openimsdk.off(SdkEvent.OnInviteeRejectedByOtherDevice, handlers.rejectedByOtherDevice);
  openimsdk.off(SdkEvent.OnHangUp, handlers.hangUp);
  openimsdk.off(SdkEvent.OnRoomParticipantConnected, handlers.participantConnected);
  openimsdk.off(SdkEvent.OnRoomParticipantDisconnected, handlers.participantDisconnected);
  openimsdk.off(SdkEvent.OnStreamChange, handlers.streamChanged);
}

本页集中提供以上 11 个通话事件的完整监听示例。refreshGroupCall(groupID) 应调用查询群组通话房间,并用查询结果刷新该群组的当前通话状态。更新参与者时按 roomID:userID 合并;不要使用事件顺序、展示名称或数组下标识别通话或参与者。退出登录、切换账号或销毁通话状态层时调用 removeCallListeners()