dataConsumer cannot receive 'message' event

Hi, I was using dataProducer and dataConsumer in React Native on Android devices to send chat messages between peers. However, I cannot receive ‘message’ event on the dataConsumer after the dataProducer called dataProducer.send(text: string). I tried to debug and log the stats using dataConsumer.getStat on the server side and the log below shows that the dataConsumer actually received 3 messages, but no one is caught by dataConsumer.on(‘message’, fn()) on the client.

"allDataConsumerStat":[[{"bufferedAmount":0,"bytesSent":499,"label":"","messagesSent":3,"protocol":"","timestamp":47556801,"type":"data-consumer"}]]

I examined the demo and the logic is simillar, so I wondered whether my config on the server was wrong.

webRtcTransportOptions :
{
  listenIps :
  [
    {
      ip          : process.env.MEDIASOUP_LISTEN_IP || '0.0.0.0',
      announcedIp : process.env.MEDIASOUP_ANNOUNCED_IP || 'myServerIp' // this is the real ip of my server
    }
  ],
    initialAvailableOutgoingBitrate : 1000000,
    minimumAvailableOutgoingBitrate : 100000,
    maxSctpMessageSize              : 262144,
    maxIncomingBitrate              : 1500000
},

I am confused with the bug and I would appreciate it so much you could tell the reason or share your idea. Thanks.

I would also post my code on both server and client for you to see if there is any problems.

// code on the client
public async createDataProducer()
{
  if (this.dataProducer == null || this.dataProducer.closed) {
    this.dataProducer = await this.sendTransport.produceData({
      ordered: true,
      priority: 'medium',
    });
  }
}

this.sendTransport.on('producedata', async (parameters, callback, errBack) => {
  try
  {
    // use signaling to tell server
    const { id } = await this.signaling.sendRequest(
      SignalMethod.produceData,
      {
        transportId          : this.sendTransport.id,
        sctpStreamParameters : parameters.sctpStreamParameters,
        label                : parameters.label,
        protocol             : parameters.protocol
      }) as { id: string };
    callback({ id });
  }
  catch (error)
  {
    errBack(error);
  }
});

// after the server prepared the dataConsumer, it would tell the client by this
this.signaling.registerListener(SignalType.notify, SignalMethod.newDataConsumer, async (data: types.DataConsumerInfo) => {
  const dataConsumer = await this.recvTransport.consumeData({
    id                  : data.dataConsumerId,
    dataProducerId      : data.dataProducerId,
    label               : data.label,
    protocol            : data.protocol,
    sctpStreamParameters: data.sctpParameters
  });

  dataConsumer.on('message', (data: string) => {
    // the event never received T_T
    console.log('Message received', data);
  });
});


// send chat message to peers
this.dataProducer.send(JSON.stringify(data));
// code on server
case RequestMethod.produceData :
{
  const {transportId, sctpStreamParameters, protocol} = request.data;
  const transport = peer.getTransport(transportId);

  let dataProducer;

  if (sctpStreamParameters == undefined) {
    dataProducer = await transport.produceData({ protocol });
  } else {
    dataProducer = await transport.produceData({
      sctpStreamParameters,
      protocol,
    })
  }

  callback(null, {id : dataProducer.id});

  const joinedPeers = this._getJoinedPeers({excludePeer : peer});

  joinedPeers.forEach((joinedPeer) => {
    this.createDataConsumer(joinedPeer, peer, dataProducer);
  })
  break;
}

async createDataConsumer (consumerPeer : PeerImpl, producerPeer : PeerImpl, dataProducer : MTypes.DataProducer) {
  const dataConsumer = await producerPeer.getConsumerTransport().consumeData({
    dataProducerId : dataProducer.id
  });

  // tell client the new dataConsumer is ready
  _notify(consumerPeer.socket, 'newDataConsumer', {
    producerPeerId : producerPeer.id,
    dataProducerId : dataProducer.id,
    dataConsumerId : dataConsumer.id,
    sctpParameters : dataConsumer.sctpStreamParameters,
    protocol : dataConsumer.protocol,
    label : dataConsumer.label
  });
}

Are you connecting the transports before passing producing/consuming data?

Hi, thank you for your reply. I actually listened the ‘connect’ event and do the connection. I forgot to post that part of code.

// code on client
this.recvTransport.on('connect', async ({dtlsParameters}, done, errBack) => {
  try {
    await this.signaling.sendRequest(SignalMethod.connectTransport, {
        transportId: this.recvTransport.id,
        dtlsParameters,
      });
    done();
  } catch (err) {
    errBack(err);
  }
});

this.sendTransport.on('connect', async ({dtlsParameters}, done, errBack) => {
  try {
    await this.signaling.sendRequest(SignalMethod.connectTransport, {
        transportId: this.sendTransport.id,
        dtlsParameters,
      });
    done();
  } catch (err) {
    errBack(err);
  }
});

I’d be checking a few things, client logs (by enabling them), DTLS state, webrtc-internals (in browser) and ensuring too that firewalls both network/software level are tended to and setup correctly with the announced ip correct of coarse.

If following a demo, it should work fine with proper settings and server configurations.