你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

将数据信道消息传递添加到通话应用

数据通道功能 API 支持在音频通话和视频通话期间进行实时消息传递。 本文介绍如何集成数据通道功能,从而在群组通话中启用参与者之间的短信交换。 除了数据通道功能之外,有许多不同的消息传送解决方案,应为特定的使用方案选择合适的解决方案。

重要说明

DataChannel 功能 API 的当前实现不支持在 Web 浏览器和对等调用方案中的本机应用之间进行直接消息传送。

创建 DataChannelSender 对象

首先,需要创建一个 DataChannelSender 对象来发送消息。 在此自定义消息传递应用程序中,建议为 channelId 分配一个数字,用来区分不同的应用程序用例。 例如,可以为自定义消息分配 channelId 1000。

const dataChannel = call.feature(Features.DataChannel);
const messageSender = dataChannel.createDataChannelSender({
    channelId: 1000
});

还有其他几个选项,例如可靠性、带宽和优先级。 现在可以忽略这些选项,并使用默认值。

创建发送方对象时,仍需要接收方对象来接收消息。

注册侦听器以获取 DataChannelReceiver 对象

要获取接收方对象,需要注册一个侦听器来捕获 dataChannelReceiverCreated 事件。 创建接收方对象时,SDK 会连同接收方对象一起发出该事件。

dataChannel.on('dataChannelReceiverCreated', receiver => {
    // receiver.channelId
    // receiver.senderParticipantIdentifier, which shows the sender id
});

在侦听器回调函数中,可以访问接收方对象,并检索 channelId 和发送方参与者 ID senderParticipantIdentifier 之类的信息。 由你负责来维护接收方对象引用,因为 SDK 会为所创建的每个接收方对象发出一次事件。

处理 DataChannelReceiver 对象的 messageReady 和 close 事件

当消息到达时,DataChannelReceiver 对象会接收消息,将其存储在内部缓冲区中,并发出 messageReady 事件。

无需注册 messageReady 事件侦听器即可接收消息,因为可以随时调用 readMessage API。

但是在最佳做法中,我们建议在 messageReady 侦听器回调中读取消息,如果消息处理需要很长时间,可将工作分流给 Web 辅助角色,以使消息接收畅通无阻。

dataChannel.on('dataChannelReceiverCreated', receiver => {
    if (receiver.channelId === 1000) {
        receiver.on('close', () => {
            console.log(`data channel id = ${receiver.channelId} from ${JSON.stringify(receiver.senderParticipantIdentifier)} is closed`);
        });
        receiver.on('messageReady', () => {
            const message = receiver.readMessage();
            // process the message
        });
    }
});

设置参与者

要指定消息的接收方,可以使用 DataChannelSender.setParticipants API。 由发送方对象来维护你提供的最新参与者列表。 参与者类型为 CommunicationIdentifier,可从remoteParticipant.identifier 获取。 有关详细信息,请参阅访问远程参与者属性

const user = call.remoteParticipants[0]; // assume the user wants to send a message to the first participant in the remoteParticipants list
messageSender.setParticipants([user.identifier]);

参与者列表限制为 64 名参与者。 如果参与者列表为空数组,SDK 会将消息广播给通话中的所有参与者。

发送和接收消息

DataChannel 功能 API 要求将数据作为 Uint8Array 类型传递。 不能使用 sendMessage API 直接发送 JavaScript 字符串。

例如,如果要发送字符串 abc,不能使用 sender.sendMessage('abc'), 而是需要先将数据序列化到字节缓冲区。

const data = (new TextEncoder()).encode('abc');
sender.sendMessage(data);

下面是发送 JSON 对象的另一个示例。

const obj = {...}; // some object
const data = (new TextEncoder()).encode(JSON.stringify(obj));
sender.sendMessage(data);

接收和解码消息。

dataChannel.on('dataChannelReceiverCreated', receiver => {
    if (receiver.channelId === 1000) {
        const textDecoder = new TextDecoder();
        receiver.on('close', () => {
            console.log(`data channel id = ${receiver.channelId} from ${JSON.stringify(receiver.senderParticipantIdentifier)} is closed`);
        });
        receiver.on('messageReady', () => {
            const message = receiver.readMessage();
            const text = textDecoder.decode(message.data);
            console.log(`from ${JSON.stringify(receiver.senderParticipantIdentifier)}:${text}`);
        });
    }
});

使用 GitHub 上的 Web 通话示例代码。

重要说明

当前的数据通道功能 API 不支持在 Web 浏览器和对等调用方案中的本机应用之间进行直接消息传送。

概述

数据通道功能 API 支持在音频通话和视频通话期间进行实时数据消息传递。 在本快速入门指南中,我们演示了如何将数据通道功能集成到调用,并使用数据通道 API 通过数据通道发送和接收数据消息。

Prerequisites

若要使用语音呼叫设置示例应用,请参阅语音呼叫快速入门

名称 说明
数据通道呼叫功能 用于启动和管理数据通道功能。
DataChannelSender 用于以发送方身份管理数据通道和发送数据。
DataChannelReceiver 用于以接收方身份管理数据通道和接收数据。
数据通道发送选项 用于表示用于创建数据通道发送方的选项。

枚举

名称 说明
DataChannelPriority 描述数据通道的优先级选项。 值:{ NORMAL, HIGH }。
DataChannelReliability 描述数据通道的可靠性选项。 值:{ LOSSY, DURABLE }。

错误代码

名称 说明
DATA_CHANNEL_FAILED_TO_START getDataChannelSender() 此错误代码可能失败,指示基础数据通道尚未准备好使用。
数据通道随机ID不可用 getDataChannelSender() 可能会因为此错误代码而失败,该错误代码表明每个可用的随机通道 ID 都在使用中。
数据通道发送器已关闭 sendMessage() 如果出现此错误代码,则表示发送方数据通道已关闭,可能会失败。
数据通道消息大小超出限制 如果出现此错误代码,则 sendMessage() 可能失败,指示消息数据大小超出限制。 可以在 DataChannelSender 中使用 getMaxMessageSizeInBytes() 来获取消息大小限制。
数据通道信息因带宽失败 如果出现此错误代码,则 sendMessage() 可能失败,指示由于带宽不足而发送消息失败。
因流量限制导致的数据通道消息失败 如果出现此错误代码,则 sendMessage() 可能失败,指示由于数据通道的总体使用情况不符合流量限制规则,消息发送失败。 有关流量限制的详细信息,请参阅数据通道概念文档

方法

启用数据通道功能

  1. 获取在预备步骤中建立的正在进行的呼叫对象。

  2. 获取数据通道功能对象。

DataChannelCallFeature dataChannelCallFeature = call.feature(Features.DATA_CHANNEL);

接收数据消息

  1. 定义 DataChannelReceiverCreatedListener。
DataChannelReceiverCreatedListener receiverCreatedListener = new DataChannelReceiverCreatedListener() {
    @Override
    public void onReceiverCreated(DataChannelReceiverCreatedEvent e) {
        DataChannelReceiver receiver = e.getReceiver(); // get the new data channel receiver
        int channelId = receiver.getChannelId(); // get the channel id
        CommunicationIdentifier senderId = receiver.getSenderIdentifier(); // get the message sender id
        // listen to the message received event and closed event from this receiver
        // receiver.addOnMessageReceivedListener(messageReceivedlistener);
        // receiver.addOnClosedListener(receiverClosedListener);
    }
};
  1. 注册 receiverCreatedListener
dataChannelCallFeature.addOnReceiverCreatedListener(receiverCreatedListener);
  1. 定义 MessageReceivedListener。
MessageReceivedListener messageReceivedListener = new MessageReceivedListener() {
    @Override
    public void onMessageReceived(PropertyChangedEvent e) {
        DataChannelMessage message = e.getReceiver().receiveMessage(); // read the data message from the receiver
        int sequence = message.getSequenceNumber(); // get the message sequence number
        byte[] data = message.getData(); // get the data content
    }
};
  1. 定义ReceiverClosedListener.
ReceiverClosedListener receiverClosedListener = new ReceiverClosedListener() {
    @Override
    public void onReceiverClosed(PropertyChangedEvent e) {
        DataChannelReceiver receiver = e.getReceiver(); // get the data channel receiver to be closed
    }
};
  1. 注册 messageReceivedListenerreceiverClosedListener
receiver.addOnMessageReceivedListener(messageReceivedlistener);
receiver.addOnClosedListener(receiverClosedListener);

发送数据消息

  1. 配置DataChannelSenderOptions
DataChannelSenderOptions options = new DataChannelSenderOptions();
options.setChannelId(1000);
options.setBitrateInKbps(32);
options.setPriority(DataChannelPriority.NORMAL);
options.setReliability(DataChannelReliability.LOSSY);

List<CommunicationIdentifier> participants = Arrays.asList( /* identifier1, identifier2, ... */ );
options.setParticipants(participants);
  1. 获取DataChannelSender并发送数据消息。
DataChannelSender dataChannelSender = dataChannelCallFeature.getDataChannelSender(options);

// msgData contains the byte[] data to be sent
dataChannelSender.sendMessage(msgData);

// change participants in the channel if needed
dataChannelSender.setParticipants(new ArrayList<CommunicationIdentifier>()); 

重要说明

当前的数据通道功能 API 不支持在 Web 浏览器和对等调用方案中的本机应用之间进行直接消息传送。

概述

数据通道功能 API 支持在音频通话和视频通话期间进行实时数据消息传递。 在本快速入门指南中,我们演示了如何将数据通道功能集成到调用,并使用数据通道 API 通过数据通道发送和接收数据消息。

Prerequisites

若要使用语音呼叫设置示例应用,请参阅语音呼叫快速入门

名称 说明
数据通道呼叫功能 (DataChannelCallFeature) 用于启动和管理数据通道功能。
DataChannelSender 用于以发送方身份管理数据通道和发送数据。
DataChannelReceiver 用于以接收方身份管理数据通道和接收数据。
数据通道发送选项 (DataChannelSenderOptions) 用于表示用于创建数据通道发送方的选项。

枚举

名称 说明
DataChannelPriority 描述数据通道的优先级选项。 值:{ normal, high }。
DataChannelReliability 描述数据通道的可靠性选项。 值:{ lossy, durable }。

错误代码

名称 说明
dataChannelFailedToStart getDataChannelSender() 此错误代码可能失败,指示基础数据通道尚未准备好使用。
数据通道随机ID不可用 getDataChannelSender() 可能出现此错误代码,表明每个可用的随机通道 ID 都已被使用。
数据通道发送者已关闭 sendMessage() 可能会失败并显示此错误代码,表示发件人已关闭。
数据通道消息大小超限 如果出现此错误代码,则 sendMessage() 可能失败,指示消息数据大小超出限制。 可以在 DataChannelSender 中使用 maxMessageSizeInBytes 来获取消息大小限制。
数据通道消息因带宽失败 如果出现此错误代码,则 sendMessage() 可能失败,指示由于带宽不足而发送消息失败。
数据通道消息因流量限制而失败 如果出现此错误代码,则 sendMessage() 可能失败,指示由于数据通道的总体使用情况不符合流量限制规则,消息发送失败。 有关流量限制的详细信息,请参阅数据通道概念文档

方法

启用数据通道功能

  1. 获取在预备步骤中建立的正在进行的呼叫对象。
  2. 获取数据通道功能对象。
var dataChannelCallFeature = self.call!.feature(Features.dataChannel)

接收数据消息

let featureDelegate = new FeatureDelegate()
let receiverDelegate = new ReceiverDelegate()
dataChannelCallFeature!.delegate = featureDelegate

class FeatureDelegate: NSObject, DataChannelCallFeatureDelegate {
    public func dataChannelCallFeature(_ dataChannelCallFeature: DataChannelCallFeature, didCreateReceiver args: DataChannelReceiverCreatedEventArgs) {
        let receiver = args.receiver // get the new data channel receiver
        let channelId = receiver.channelId // get the channel id
        let senderId = receiver.senderIdentifier // get the message sender id

        receiver.delegate = receiverDelegate
    }
}

class ReceiverDelegate: NSObject, DataChannelReceiverDelegate {
    public func dataChannelReceiver(_ dataChannelReceiver: DataChannelReceiver, didReceiveMessage args: PropertyChangedEventArgs) {
        let message = dataChannelReceiver.receiveMessage() // read the data message from the receiver
        let sequence = message?.sequenceNumber // get the message sequence number
        let data = message?.data // get the data content
    }
    
    public func dataChannelReceiver(_ dataChannelReceiver: DataChannelReceiver, didClose args: PropertyChangedEventArgs) {
       let channelId = dataChannelReceiver.channelId // get the data channel id to be closed
    }
}

发送数据消息

  1. 配置 DataChannelSenderOptions。
let options = new DataChannelSenderOptions()
options.channelId = 1000
options.bitrateInKbps = 32
options.priority = DataChannelPriority.normal
options.reliability = DataChannelReliability.lossy

let communicationIdentifiers: [CommunicationIdentifier] = [ /* identifier1, identifier2, ... */ ]
options.participants = communicationIdentifiers
  1. 定义 DataChannelSender 并发送数据消息
DataChannelSender sender = dataChannelCallFeature.getDataChannelSender(options)

// msgData contains the data to be sent
sender.sendMessage(msgData)

// change participants in the channel if needed
let participants: [CommunicationIdentifier] = []
dataChannelSender.setParticipants(participants: participants)

重要说明

当前的数据通道功能 API 不支持在 Web 浏览器和对等调用方案中的本机应用之间进行直接消息传送。

概述

数据通道功能 API 支持在音频通话和视频通话期间进行实时数据消息传递。 在本快速入门指南中,我们演示了如何将数据通道功能集成到调用,并使用数据通道 API 通过数据通道发送和接收数据消息。

Prerequisites

若要使用语音呼叫设置示例应用,请参阅语音呼叫快速入门

名称 说明
数据通道呼叫特性 (DataChannelCallFeature) 用于启动和管理数据通道功能。
DataChannelSender 用于以发送方身份管理数据通道和发送数据。
DataChannelReceiver 用于以接收方身份管理数据通道和接收数据。
DataChannelSenderOptions 用于表示用于创建数据通道发送方的选项。

枚举

名称 说明
DataChannelPriority 描述数据通道的优先级选项。 值:{ Normal, High }。
DataChannelReliability 描述数据通道的可靠性选项。 值:{ Lossy, Durable }。

错误代码

名称 说明
数据通道启动失败 GetDataChannelSender() 此错误代码可能失败,指示基础数据通道尚未准备好使用。
数据通道随机ID不可用 GetDataChannelSender() 可能因此错误代码而失败,这表明每个可用的随机通道 ID 都已被使用。
DataChannel发送器已关闭 SendMessage() 如果出现此错误代码,则表示发送方数据通道已关闭,可能会失败。
数据通道消息大小超出限制 如果出现此错误代码,则 SendMessage() 可能失败,指示消息数据大小超出限制。 可以在 DataChannelSender 中使用 MaxMessageSizeInBytes 来获取消息大小限制。
因带宽导致的 DataChannel 消息故障 如果出现此错误代码,则 SendMessage() 可能失败,指示由于带宽不足而发送消息失败。
因流量限制导致的数据通道消息失败 如果出现此错误代码,则 SendMessage() 可能失败,指示由于数据通道的总体使用情况不符合流量限制规则,消息发送失败。 有关流量限制的详细信息,请参阅数据通道概念文档

方法

启用数据通道功能

  1. 获取在预备步骤中建立的正在进行的呼叫对象。
  2. 获取数据通道功能对象。
DataChannelCallFeature dataChannelCallFeature = call.Features.DataChannel;

接收数据消息

  1. 定义 DataChannelReceiverCreated 事件处理程序。
void DataChannelReceiverCreatedHandler(object sender, DataChannelReceiverCreatedEventArgs args) 
{
    DataChannelReceiver receiver = args.Receiver; // get the new data channel receiver
    int channelId = receiver.ChannelId; // get the channel id
    CallIdentifier senderId = receiver.SenderIdentifier; // get the message sender id
    
    // add event handlers for the message received event and closed event from this receiver
    // receiver.MessageReceived += MessageReceivedHandler;
    // receiver.Closed += ReceiverClosedHandler;
}
  1. 附加 DataChannelReceiverCreatedHandler
dataChannelCallFeature.ReceiverCreated += DataChannelReceiverCreatedHandler;
  1. 定义 MessageReceived 事件处理程序。
void MessageReceivedHandler(object sender, PropertyChangedEventArgs args) 
{
    DataChannelMessage message = (sender as DataChannelReceiver).ReceiveMessage(); // read the data message from the receiver
    long sequence = message.SequenceNumber; // get the message sequence number
    byte[] data = message.Data; // get the data content
}
  1. 定义 Closed 事件处理程序。
void ReceiverClosedHandler(object sender, PropertyChangedEventArgs args) 
{
    DataChannelReceiver receiver = sender as DataChannelReceiver; // get the data channel receiver to be closed
};
  1. 附加 MessageReceivedHandlerReceiverClosedHandler
receiver.MessageReceived += MessageReceivedHandler;
receiver.Closed += ReceiverClosedHandler;

发送数据消息

  1. 配置 DataChannelSenderOptions。
DataChannelSenderOptions options = new DataChannelSenderOptions();
options.ChannelId = 1000;
options.BitrateInKbps = 32;
options.Priority = DataChannelPriority.Normal;
options.Reliability = DataChannelReliability.Lossy;
var participants = new List<CallIdentifier> { /* identifier1, identifier2, ... */ };
options.Participants = participants.AsReadOnly();
  1. 定义 DataChannelSender 并发送数据消息
DataChannelSender sender = dataChannelCallFeature.GetDataChannelSender(options);
// msgData contains the byte[] data to be sent
sender.SendMessage(msgData);
// change participants in the channel if needed
sender.SetParticipants(new List<CallIdentifier>().AsReadOnly()); 

Next steps

有关详细信息,请参见: