DataChannel over videoroom

852 views
Skip to first unread message

Roberto Ostinelli

unread,
Apr 26, 2022, 9:33:11 AM4/26/22
to meetecho-janus
All,
I'm unsuccessful in sending data over data channels in a videoroom. I've browsed various documentation and the group here, so this is where I'm at.

I have publisher 1 join in a room, and I create a data channel over their PC with pc.createDataChannel("JanusDataChannel"). The channel label comes from <https://github.com/meetecho/janus-gateway/issues/124> and from <https://github.com/meetecho/janus-gateway/blob/v0.12.1/test/echo.py#L204>. I can see in the SDP offer / answer exchange that data is negotiated, as for instance in the SDP answer I see:

a=group:BUNDLE audio video data
a=mid:data
a=sctpmap:5000 webrtc-datachannel 65535


I have a publisher 2 join in the same room, then issue a subscribe request in the videoroom for publisher 1, then negotiation happens, and publisher 2 successfully receives video / audio from publisher 1.

Now, when I send data from publisher 1 with channel.send("some-data") I see in Janus logs that the data has been received:

[7807699545221270] SCTP data received of length 9 on channel with id 0.
[7807699545221270] Incoming SCTP contents: some-data
Got a text DataChannel message (9 bytes) to forward


However, publisher 2 never receives this data.

I also read from <https://groups.google.com/g/meetecho-janus/c/vOkIkW2c0Gs/m/1NTGG4YNAQAJ> that "The core expects subscribers to create a default datachannel first", so I've tried also creating a data channel on publisher's 2 PC that subscribes to 1, to no avail. I've also tried creating a default data channel everywhere.

Can some kind soul tell me what I'm missing?

Thank you.
r.

Lorenzo Miniero

unread,
Apr 26, 2022, 9:41:14 AM4/26/22
to meetecho-janus
You get data from a subscriber PC, not a publisher PC. The publisher data channel can only be used for sending, not receiving.
I made a quick test by adding a data:true to the media object in both createOffer and createAnswer of the videoroomtest.js demo, and data worked as expected.
Of course, you'll need to make sure the subscriber actually does subscribe to the publisher's data (and not just audio/video), or data won't be relayed.

L.

Roberto Ostinelli

unread,
Apr 26, 2022, 10:03:49 AM4/26/22
to meetecho-janus

You get data from a subscriber PC, not a publisher PC. The publisher data channel can only be used for sending, not receiving.

I'm calling them both publishers as per your teminology, if I'm not mistaken. Publisher 2 is the subscriber of Publisher 1: I'm sending data from Publisher 1 so I'd expect Publisher 2 to receive data. Is this incorrect?
 
I made a quick test by adding a data:true to the media object in both createOffer and createAnswer of the videoroomtest.js demo, and data worked as expected.
Of course, you'll need to make sure the subscriber actually does subscribe to the publisher's data (and not just audio/video), or data won't be relayed.

I'm sending a "join" request with ptype set to "subscriber" which returns an SDP that contains data fields in it. Is it something else that needs to be done?

 

Roberto Ostinelli

unread,
Apr 26, 2022, 10:09:55 AM4/26/22
to meetecho-janus
BTW I'm using https://github.com/meetecho/janus-gateway/blob/v0.12.1/test/echo.py as a reference, however @pc.on("datachannel") never gets called (referring to the aiortc example here https://github.com/aiortc/aiortc/blob/main/examples/datachannel-cli/cli.py#L53)

Roberto Ostinelli

unread,
Apr 27, 2022, 6:20:15 AM4/27/22
to meetecho-janus
All,
I made some progress but unfortunately I'm still stuck, and I'd appreciate some help if possible.

I have 2 publishers (A and B) in a room, each one with their own RTCPeerConnection to Janus, sending audio / video media.
I've created a data channel on both of these connections by calling pc.createDataChannel('JanusDataChannel') on each one before negotiation, and I can see that data fields are included in the offer / answer SDPs.

Then, B becomes a subscriber of A.
For this, a new subscriber RTCPeerConnection gets created on B to receive media from A.
On this connection I also call pc.createDataChannel('JanusDataChannel') before negotiation, and here too I can see the data fields in the SDPs.
B is now successfully receiving audio / video from A on this connection.

For this connection (B to receive data from A), I have is something like this:

local_channel = pc.createDataChannel('JanusDataChannel')

@local_channel.on("open")
def on_open():
    log_to_console(f"*************** LOCAL SUBSCRIBER CHANNEL OPEN")

@local_channel.on("message")
def on_message(message):
    log_to_console(f"*************** LOCAL SUBSCRIBER CHANNEL MESSAGE RECEIVED {message}")


Then I send data from A by calling channel.send("some-data") on A's RTCPeerConnection channel.
I see on B that the subscriber RTCPeerConnection' channel gets opened at this moment ("onopen"), but no message is received.

So I send data again from A by calling channel.send("some-data-2") and I now see on B that the subscriber RTCPeerConnection channel receives the second message ("onmessage"), so "some-data-2", but the original data "some-data" never was received.

Quick logs:

*************** SENDING some-data ON <aiortc.rtcdatachannel.RTCDataChannel object at 0x111a54460>
*************** SENT!
*************** LOCAL SUBSCRIBER CHANNEL OPEN

*************** SENDING some-data-2 ON <aiortc.rtcdatachannel.RTCDataChannel object at 0x111a54460>
*************** SENT!
*************** LOCAL SUBSCRIBER CHANNEL MESSAGE RECEIVED some-data-2


Can someone tell me what I am missing to be able to also receive the first message?

Thank you,
r.

Sarsaparilla Sunset

unread,
Jan 9, 2023, 8:24:35 PM1/9/23
to meetecho-janus
As of the latest janus.js, to send data from publisher to all subscribers:

1. publisher must request dataChannel support when sending Offer, and subscriber must request dataChannel support when sending Answer, by specifying:
tracks: [
  {type: "data"},
  ...
]
Janus will create a default data channel for you, so you don't have to fiddle directly with the PeerConnection.

2. then to send and receive:
publisherPluginHandle.data({text: "whatever"})
subscriberPluginHandle.ondata = function(data) {...}
Reply all
Reply to author
Forward
0 new messages