Send data channel messages only to "video" peer connections

Data channel messages are expected to be sent only to peer connections
with "video" type, which provide the audio and video tracks of the
participant (and, in fact, peer connections for screen shares do not
even have data channels enabled in the WebUI).

Note that this could change if at some point several audio/video tracks
are sent in the same peer connection, or if "speaking" messages are
added to screen shares, but that will be addressed if/when that happens.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
Daniel Calviño Sánchez 2024-10-25 14:38:59 +02:00 committed by Marcel Hibbe
parent 3e36c85015
commit 36a29ed36e
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
4 changed files with 64 additions and 4 deletions

View File

@ -18,7 +18,9 @@ import java.util.List;
* <p>
* Note that, unlike signaling messages, data channel messages require a peer connection. Therefore data channel
* messages may not be received by a participant if there is no peer connection with that participant (for example, if
* neither the local and remote participants have publishing rights).
* neither the local and remote participants have publishing rights). Moreover, data channel messages are expected to
* be received only on peer connections with type "video", so data channel messages will not be sent on other peer
* connections.
*/
public abstract class MessageSender {
@ -37,7 +39,8 @@ public abstract class MessageSender {
protected PeerConnectionWrapper getPeerConnectionWrapper(String sessionId) {
for (PeerConnectionWrapper peerConnectionWrapper: peerConnectionWrappers) {
if (peerConnectionWrapper.getSessionId().equals(sessionId)) {
if (peerConnectionWrapper.getSessionId().equals(sessionId)
&& "video".equals(peerConnectionWrapper.getVideoStreamType())) {
return peerConnectionWrapper;
}
}

View File

@ -22,7 +22,9 @@ public class MessageSenderNoMcu extends MessageSender {
public void sendToAll(DataChannelMessage dataChannelMessage) {
for (PeerConnectionWrapper peerConnectionWrapper: peerConnectionWrappers) {
peerConnectionWrapper.send(dataChannelMessage);
if ("video".equals(peerConnectionWrapper.getVideoStreamType())){
peerConnectionWrapper.send(dataChannelMessage);
}
}
}
}

View File

@ -18,7 +18,10 @@ class MessageSenderMcuTest {
private var peerConnectionWrappers: MutableList<PeerConnectionWrapper?>? = null
private var peerConnectionWrapper1: PeerConnectionWrapper? = null
private var peerConnectionWrapper2: PeerConnectionWrapper? = null
private var peerConnectionWrapper2Screen: PeerConnectionWrapper? = null
private var peerConnectionWrapper4Screen: PeerConnectionWrapper? = null
private var ownPeerConnectionWrapper: PeerConnectionWrapper? = null
private var ownPeerConnectionWrapperScreen: PeerConnectionWrapper? = null
private var messageSender: MessageSenderMcu? = null
@ -36,11 +39,26 @@ class MessageSenderMcuTest {
Mockito.`when`(peerConnectionWrapper2!!.videoStreamType).thenReturn("video")
peerConnectionWrappers!!.add(peerConnectionWrapper2)
peerConnectionWrapper2Screen = Mockito.mock(PeerConnectionWrapper::class.java)
Mockito.`when`(peerConnectionWrapper2Screen!!.sessionId).thenReturn("theSessionId2")
Mockito.`when`(peerConnectionWrapper2Screen!!.videoStreamType).thenReturn("screen")
peerConnectionWrappers!!.add(peerConnectionWrapper2Screen)
peerConnectionWrapper4Screen = Mockito.mock(PeerConnectionWrapper::class.java)
Mockito.`when`(peerConnectionWrapper4Screen!!.sessionId).thenReturn("theSessionId4")
Mockito.`when`(peerConnectionWrapper4Screen!!.videoStreamType).thenReturn("screen")
peerConnectionWrappers!!.add(peerConnectionWrapper4Screen)
ownPeerConnectionWrapper = Mockito.mock(PeerConnectionWrapper::class.java)
Mockito.`when`(ownPeerConnectionWrapper!!.sessionId).thenReturn("ownSessionId")
Mockito.`when`(ownPeerConnectionWrapper!!.videoStreamType).thenReturn("video")
peerConnectionWrappers!!.add(ownPeerConnectionWrapper)
ownPeerConnectionWrapperScreen = Mockito.mock(PeerConnectionWrapper::class.java)
Mockito.`when`(ownPeerConnectionWrapperScreen!!.sessionId).thenReturn("ownSessionId")
Mockito.`when`(ownPeerConnectionWrapperScreen!!.videoStreamType).thenReturn("screen")
peerConnectionWrappers!!.add(ownPeerConnectionWrapperScreen)
messageSender = MessageSenderMcu(peerConnectionWrappers, "ownSessionId")
}
@ -50,19 +68,41 @@ class MessageSenderMcuTest {
messageSender!!.sendToAll(message)
Mockito.verify(ownPeerConnectionWrapper!!).send(message)
Mockito.verify(ownPeerConnectionWrapperScreen!!, never()).send(message)
Mockito.verify(peerConnectionWrapper1!!, never()).send(message)
Mockito.verify(peerConnectionWrapper2!!, never()).send(message)
Mockito.verify(peerConnectionWrapper2Screen!!, never()).send(message)
Mockito.verify(peerConnectionWrapper4Screen!!, never()).send(message)
}
@Test
fun testSendDataChannelMessageToAllWithoutOwnPeerConnection() {
fun testSendDataChannelMessageToAllIfOwnScreenPeerConnection() {
peerConnectionWrappers!!.remove(ownPeerConnectionWrapper)
val message = DataChannelMessage()
messageSender!!.sendToAll(message)
Mockito.verify(ownPeerConnectionWrapper!!, never()).send(message)
Mockito.verify(ownPeerConnectionWrapperScreen!!, never()).send(message)
Mockito.verify(peerConnectionWrapper1!!, never()).send(message)
Mockito.verify(peerConnectionWrapper2!!, never()).send(message)
Mockito.verify(peerConnectionWrapper2Screen!!, never()).send(message)
Mockito.verify(peerConnectionWrapper4Screen!!, never()).send(message)
}
@Test
fun testSendDataChannelMessageToAllWithoutOwnPeerConnection() {
peerConnectionWrappers!!.remove(ownPeerConnectionWrapper)
peerConnectionWrappers!!.remove(ownPeerConnectionWrapperScreen)
val message = DataChannelMessage()
messageSender!!.sendToAll(message)
Mockito.verify(ownPeerConnectionWrapper!!, never()).send(message)
Mockito.verify(ownPeerConnectionWrapperScreen!!, never()).send(message)
Mockito.verify(peerConnectionWrapper1!!, never()).send(message)
Mockito.verify(peerConnectionWrapper2!!, never()).send(message)
Mockito.verify(peerConnectionWrapper2Screen!!, never()).send(message)
Mockito.verify(peerConnectionWrapper4Screen!!, never()).send(message)
}
}

View File

@ -11,12 +11,15 @@ import com.nextcloud.talk.webrtc.PeerConnectionWrapper
import org.junit.Before
import org.junit.Test
import org.mockito.Mockito
import org.mockito.Mockito.never
class MessageSenderNoMcuTest {
private var peerConnectionWrappers: MutableList<PeerConnectionWrapper?>? = null
private var peerConnectionWrapper1: PeerConnectionWrapper? = null
private var peerConnectionWrapper2: PeerConnectionWrapper? = null
private var peerConnectionWrapper2Screen: PeerConnectionWrapper? = null
private var peerConnectionWrapper4Screen: PeerConnectionWrapper? = null
private var messageSender: MessageSenderNoMcu? = null
@ -34,6 +37,16 @@ class MessageSenderNoMcuTest {
Mockito.`when`(peerConnectionWrapper2!!.videoStreamType).thenReturn("video")
peerConnectionWrappers!!.add(peerConnectionWrapper2)
peerConnectionWrapper2Screen = Mockito.mock(PeerConnectionWrapper::class.java)
Mockito.`when`(peerConnectionWrapper2Screen!!.sessionId).thenReturn("theSessionId2")
Mockito.`when`(peerConnectionWrapper2Screen!!.videoStreamType).thenReturn("screen")
peerConnectionWrappers!!.add(peerConnectionWrapper2Screen)
peerConnectionWrapper4Screen = Mockito.mock(PeerConnectionWrapper::class.java)
Mockito.`when`(peerConnectionWrapper4Screen!!.sessionId).thenReturn("theSessionId4")
Mockito.`when`(peerConnectionWrapper4Screen!!.videoStreamType).thenReturn("screen")
peerConnectionWrappers!!.add(peerConnectionWrapper4Screen)
messageSender = MessageSenderNoMcu(peerConnectionWrappers)
}
@ -44,5 +57,7 @@ class MessageSenderNoMcuTest {
Mockito.verify(peerConnectionWrapper1!!).send(message)
Mockito.verify(peerConnectionWrapper2!!).send(message)
Mockito.verify(peerConnectionWrapper2Screen!!, never()).send(message)
Mockito.verify(peerConnectionWrapper4Screen!!, never()).send(message)
}
}