I have tried to implement datachannel on Android. I successfully send the data from android to web using datachannel.
However, whenever I try to send the data from the web to android, android doesn't receive the data and onMessage() is never triggered.
I don't understand why this happens. Here is how I implement DataChannel.Observer.
private class DcObserver implements DataChannel.Observer {
// removed other overrided messages for clarity
@Override
public void onMessage(DataChannel.Buffer buffer) {
Toast.makeText(getApplicationContext(),
"Some Data has been received", Toast.LENGTH_SHORT)
.show();
Log.d("Data", "Some Data has been received");
}
}
I create the object for every PeerConnection object. I have this class which contains the PeerConnection object.
private class FilePeer implements SdpObserver {
private PeerConnection pc;
private DataChannel dc;
// removed other overrided methods for clarity
public FilePeer() {
PcObserver pcObserver = new PcObserver();
pc = factory.createPeerConnection(RTCConfig.getIceServer(),
RTCConfig.getMediaConstraints(), pcObserver);
dc = pc.createDataChannel("sendDataChannel", new DataChannel.Init());
//DcObserver dcObserver = new DcObserver();
//dc.registerObserver(dcObserver); // This one crashes the app, therefore, getting the datachannel using onDataChannel
}
}
This is how PcObserver class looks like.
private class PcObserver implements PeerConnection.Observer{
@Override
public void onDataChannel(final DataChannel dataChannel) {
runOnUiThread(new Runnable() {
public void run() {
peer.dc = dataChannel;
DcObserver dcObserver = new DcObserver();
peer.dc.registerObserver(dcObserver);
//dataChannel.registerObserver(dcObserver);
}
});
}
// other methods are removed for clarity
}
I think I am doing something wrong with peer.dc.registerObserver(dcObserver);
But I don't know what.
I found the solution for this problem on webrtc group.
I need to hold on to a reference of the observer to make sure it does not get destroyed when the DataChannel calls back.
One more thing, we need to do is remove peer.dc = dataChannel;
inside onDataChannel();
,
The following code works fine for me now:
public void onDataChannel(final DataChannel dataChannel) {
final DataChannel dc = dataChannel;
runOnUiThread(new Runnable() {
public void run() {
DcObserver dcObserver = new DcObserver();
peer.dc.registerObserver(dcObserver);
}
});
}