Skip to content

Commit

Permalink
Merge pull request #9 from algorandfoundation/feat/turn-server-fallback
Browse files Browse the repository at this point in the history
feat: turn-server-fallback
  • Loading branch information
PhearZero committed May 31, 2024
2 parents 0bde39f + 2b363ff commit 90a4b44
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 20 deletions.
16 changes: 13 additions & 3 deletions demo/src/main/java/foundation/algorand/demo/AnswerActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ import java.security.Security
import java.util.concurrent.Executor
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

import org.webrtc.PeerConnection

class AnswerActivity : AppCompatActivity() {
companion object {
Expand All @@ -75,6 +75,16 @@ class AnswerActivity : AppCompatActivity() {

private val cookieJar = Cookies()

private val iceServers = listOf(
PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer(),
PeerConnection.IceServer.builder("stun:stun1.l.google.com:19302").createIceServer(),
PeerConnection.IceServer.builder("stun:stun2.l.google.com:19302").createIceServer(),
PeerConnection.IceServer.builder("turn:global.relay.metered.ca:80").setUsername("fc7708976bf5d60be20c5a1d").setPassword("sVpEREQGGhXOw4gX").createIceServer(),
PeerConnection.IceServer.builder("turn:global.relay.metered.ca:80?transport=tcp").setUsername("fc7708976bf5d60be20c5a1d").setPassword("sVpEREQGGhXOw4gX").createIceServer(),
PeerConnection.IceServer.builder("turn:global.relay.metered.ca:443").setUsername("fc7708976bf5d60be20c5a1d").setPassword("sVpEREQGGhXOw4gX").createIceServer(),
PeerConnection.IceServer.builder("turns:global.relay.metered.ca:443?transport=tcp").setUsername("fc7708976bf5d60be20c5a1d").setPassword("sVpEREQGGhXOw4gX").createIceServer()
)

// Third Party APIs
private var httpClient = OkHttpClient.Builder()
.cookieJar(cookieJar)
Expand Down Expand Up @@ -552,7 +562,7 @@ class AnswerActivity : AppCompatActivity() {
)
)
// Create P2P Channel
val dc = signalClient?.peer(msg.requestId, "answer" )
val dc = signalClient?.peer(msg.requestId, "answer", iceServers)
// Handle the DataChannel
signalClient?.handleDataChannel(dc!!, {
handleMessages(msg, it)
Expand Down Expand Up @@ -651,7 +661,7 @@ class AnswerActivity : AppCompatActivity() {
val msg = viewModel.message.value!!
val account = viewModel.account.value!!
// Connect to the service then handle state changes and messages
val dc = signalClient?.peer(msg.requestId, "answer" )
val dc = signalClient?.peer(msg.requestId, "answer", iceServers)
Log.d(TAG, "DataChannel: $dc")
signalClient?.handleDataChannel(dc!!, {
handleMessages(msg, it)
Expand Down
14 changes: 12 additions & 2 deletions demo/src/main/java/foundation/algorand/demo/OfferActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import foundation.algorand.demo.databinding.ActivityOfferBinding
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import org.json.JSONObject

import org.webrtc.PeerConnection

/**
* Offer Activity
Expand All @@ -32,6 +32,16 @@ class OfferActivity : AppCompatActivity() {

private val cookieJar = Cookies()

private val iceServers = listOf(
PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer(),
PeerConnection.IceServer.builder("stun:stun1.l.google.com:19302").createIceServer(),
PeerConnection.IceServer.builder("stun:stun2.l.google.com:19302").createIceServer(),
PeerConnection.IceServer.builder("turn:global.relay.metered.ca:80").setUsername("fc7708976bf5d60be20c5a1d").setPassword("sVpEREQGGhXOw4gX").createIceServer(),
PeerConnection.IceServer.builder("turn:global.relay.metered.ca:80?transport=tcp").setUsername("fc7708976bf5d60be20c5a1d").setPassword("sVpEREQGGhXOw4gX").createIceServer(),
PeerConnection.IceServer.builder("turn:global.relay.metered.ca:443").setUsername("fc7708976bf5d60be20c5a1d").setPassword("sVpEREQGGhXOw4gX").createIceServer(),
PeerConnection.IceServer.builder("turns:global.relay.metered.ca:443?transport=tcp").setUsername("fc7708976bf5d60be20c5a1d").setPassword("sVpEREQGGhXOw4gX").createIceServer()
)

// Third Party APIs
private var httpClient = OkHttpClient.Builder()
.cookieJar(cookieJar)
Expand All @@ -50,7 +60,7 @@ class OfferActivity : AppCompatActivity() {
binding.qrCodeImageView.setImageBitmap(signalClient.qrCode(requestId, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_round)))
viewModel.setMessage(AuthMessage(url, requestId))
lifecycleScope.launch {
val dc = signalClient.peer(requestId, "offer")
val dc = signalClient.peer(requestId, "offer", iceServers)
Log.d(TAG, "Data Channel: $dc")
signalClient.handleDataChannel(dc!!, {
// TODO: AVM Provider Handler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import org.json.JSONObject
import org.webrtc.PeerConnection
import org.webrtc.DataChannel
import org.webrtc.IceCandidate
import org.webrtc.SessionDescription
Expand Down Expand Up @@ -92,7 +93,7 @@ class SignalClient @Inject constructor(
*
* The type parameter is used to specify the type of remote peer
*/
override suspend fun peer(requestId: Double, type: String): DataChannel? {
override suspend fun peer(requestId: Double, type: String, iceServers: List<PeerConnection.IceServer>?): DataChannel? {
createSocket()
return suspendCoroutine { continuation ->
scope.launch {
Expand Down Expand Up @@ -122,23 +123,25 @@ class SignalClient @Inject constructor(
peerClient!!.createPeerConnection(
// Handle Local ICECandidates
{ iceCandidate ->
Log.d(
TAG,
"onIce${clientType.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString() }}Candidate(${iceCandidate.toJSON()})"
)
// Send Local ICECandidates to Peer
socket?.emit("${clientType}-candidate", iceCandidate.toJSON())
}, {
// Handle a Data Channel from the Peer
// This only happens for a client that creates an Answer,
// Offer clients are responsible for creating a datachannel
continuation.resume(it)
})
Log.d(
TAG,
"onIce${clientType.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ROOT) else it.toString() }}Candidate(${iceCandidate.toJSON()})"
)
// Send Local ICECandidates to Peer
socket?.emit("${clientType}-candidate", iceCandidate.toJSON())
},{
// Handle a Data Channel from the Peer
// This only happens for a client that creates an Answer,
// Offer clients are responsible for creating a datachannel
continuation.resume(it)
},
iceServers
)

// Wait for Offer, then create Answer
if (type === "offer") {
val sdp = signal(type)
Log.d(TAG, "Recieved the SDP!(${sdp})")
Log.d(TAG, "Recieved the SDP!(${sdp})")
peerClient?.setRemoteDescription(sdp)
Log.d(TAG, "Set the SDP!(${sdp})")
if(candidatesBuffer.isNotEmpty()){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.graphics.Bitmap
import okhttp3.OkHttpClient
import io.socket.client.Socket
import org.json.JSONObject
import org.webrtc.PeerConnection
import org.webrtc.DataChannel
import org.webrtc.SessionDescription
import kotlin.math.floor
Expand Down Expand Up @@ -52,7 +53,7 @@ interface SignalInterface {
/**
* Top Level Peer Connection
*/
suspend fun peer(requestId: Double, type: String): DataChannel?
suspend fun peer(requestId: Double, type: String, iceServers: List<PeerConnection.IceServer>?): DataChannel?
/**
* Waits for a remote client to authenticate with the server
*/
Expand Down

0 comments on commit 90a4b44

Please sign in to comment.