All Products
Search
Document Center

ApsaraVideo Live:Custom Message Sending and Receiving

Last Updated:Mar 11, 2026

This topic describes how to send and receive messages using the Data Channel in the ApsaraVideo Real-time Communication (ARTC) SDK.

Sample Code

Android client custom message sending and receiving: Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/DataChannelMessage/DataChannelMessageActivity.java.

iOS client custom message sending and receiving: iOS/ARTCExample/BasicUsage/DataChannelMessage/DataChannelMessageVC.swift.

Harmony client custom message sending and receiving: Harmony/ARTCExample/entry/src/main/ets/pages/basicusage/DataChannelMessagePage.ets.

Prerequisites

Note

The ARTC DataChannel feature depends on the streamer pushing audio or video streams. Therefore, use it only after establishing a call and starting to push audio or video. If your scenario does not require actual audio or video streaming, push a silent audio stream to meet this dependency and enable the DataChannel.

Feature Implementation

image.jpeg

Note

Streamers can send and receive messages. Viewers can only receive messages.

Enable Custom Message Channel

ARTC does not enable the custom message channel by default. Call the setParameter interface to enable it. You can call this interface before or after joining a channel.

Android

param = "{\"data\":{\"enablePubDataChannel\":true" + ",\"enableSubDataChannel\":true}}";
mAliRtcEngine.setParameter(param);

iOS

NSString* parameter = [NSString stringWithFormat:@"{\"data\":{\"enablePubDataChannel\":true,\"enableSubDataChannel\":true}}"];
[self.engine setParameter:parameter];

Harmony

const param = '{"data":{"enablePubDataChannel":true,"enableSubDataChannel":true}}';
this.rtcEngine.setParameter(param);

Web

// The Web client must call this before joinChannel
mAliRtcEngine.setParameter(
  JSON.stringify({
    data: {
      enablePubDataChannel: true,
      enableSubDataChannel: true,
    },
  }),
);

Mac

NSString* parameter = [NSString stringWithFormat:@"{\"data\":{\"enablePubDataChannel\":true,\"enableSubDataChannel\":true}}"];
[self.engine setParameter:parameter];

Windows

char * param = "{\"data\":{\"enablePubDataChannel\":true,\"enableSubDataChannel\":true}}";
mAliRtcEngine->SetParameter(param);

Send Custom Messages

After establishing a DataChannel, use the sendDataChannelMsg interface.

Important
  • Streamers can send and receive messages. Viewers can only receive messages.

  • Call setParameter to enable the custom message channel.

  • Data sending has the following limits:

    • Bitrate limit: 30 KB/s.

    • The data channel can send up to 60 data packets per second, with each packet limited to 1 KB.

Android

AliRtcEngine.AliRtcDataChannelMsg msg = new AliRtcEngine.AliRtcDataChannelMsg();
msg.type = AliRtcEngine.AliRtcDataMsgType.AliEngineDataMsgCustom;
/* All types of data are supported, including text and images. */
msg.data =  xxxx;
mAliRtcEngine.sendDataChannelMsg(msg);

iOS

AliRtcDataChannelMsg* msg = [[AliRtcDataChannelMsg alloc] init];
msg.type = AliRtcDataMsgCustom;
/* All types of data are supported, including text and images. */
msg.data = xxxxx;
[self.engine sendDataChannelMessage:msg];

Harmony

const msg = new AliRtcDataChannelMsg();
msg.type = AliRtcDataMsgType.AliRtcDataChannelCustom;

const seiData = this.stringToArrayBuffer(this.SendText);
msg.data = seiData;

// Send message
const res = this.rtcEngine.sendDataChannelMsg(msg);

Web

const data = new TextEncoder().encode('xxxx');
// Data can be any type (such as text or images), in ArrayBuffer format.
mAliRtcEngine.sendDataChannelMessage(
  new AliRtcDataChannelMsg(data), 
);

Mac

AliRtcDataChannelMsg* msg = [[AliRtcDataChannelMsg alloc] init];
msg.type = AliRtcDataMsgCustom;
/* All types of data are supported, including text and images. */
msg.data = xxxxx;
[self.engine sendDataChannelMessage:msg];

Windows

AliEngineDataChannelMsg msg;
msg.type = AliEngineDataChannelCustom;
/* All types of data are supported, including text and images. */
msg.data =  data;
msg.dataLen = dataLength;
mAliRtcEngine->SendDataChannelMessage(msg);

Receive Custom Messages

Receive custom messages by listening for the onDataChannelMessage callback.

Android

// When AliRtcEngineNotify is triggered
public void onDataChannelMessage(String uid, AliRtcEngine.AliRtcDataChannelMsg msg) {
    /* TODO: Write the logic for processing custom messages. */
}

iOS

- (void)onDataChannelMessage:(NSString *_Nonnull)uid controlMsg:(AliRtcDataChannelMsg*_Nonnull)controlMsg {
	/* TODO: Write the logic for processing custom messages. */
}

Harmony

// Data channel message reception callback
listener.onDataChannelMessage((uid: string, msg: AliRtcDataChannelMsg) => {
  console.info(`Received data channel message: uid=${uid}, type=${msg.type}`);
  /* TODO: Write the logic for processing custom messages. */
});

Web

mAliRtcEngine.on('dataChannelMsg', (uid, message) => {
  // Write the logic for processing custom messages.
  console.log('dataChannelMsg', uid, message);
});

Mac

- (void)onDataChannelMessage:(NSString *)uid controlMsg:(AliRtcDataChannelMsg *)controlMsg {
    /* TODO: Write the logic for processing custom messages. */
}

Windows

public:
virtual void OnDataChannelMessage(const char* uid, const AliEngineDataChannelMsg& msg) override {
    /* TODO: Write the logic for processing custom messages. */
}