1
1
package io.xconn.wampwebrtc
2
2
3
3
import android.content.Context
4
- import io.xconn.wampproto.serializers.CBORSerializer
5
4
import io.xconn.xconn.Client
5
+ import io.xconn.xconn.Event
6
+ import kotlinx.coroutines.CoroutineScope
7
+ import kotlinx.coroutines.Dispatchers
6
8
import kotlinx.coroutines.GlobalScope
9
+ import kotlinx.coroutines.Job
7
10
import kotlinx.coroutines.launch
8
11
import org.json.JSONArray
9
12
import org.json.JSONObject
@@ -16,8 +19,11 @@ class WebRTC(
16
19
private val context : Context ,
17
20
private val queue : LinkedBlockingDeque <ByteArray >,
18
21
) {
22
+ private lateinit var offerer: Offerer
23
+ private val couroutineScope = CoroutineScope (Dispatchers .Default + Job ())
24
+
19
25
suspend fun connect (config : ClientConfig ): WebRTCSession {
20
- val client = Client (serializer = CBORSerializer () )
26
+ val client = Client (serializer = config.serializer )
21
27
val session = client.connect(config.url, config.realm)
22
28
23
29
val requestID = UUID .randomUUID().toString()
@@ -31,7 +37,7 @@ class WebRTC(
31
37
)
32
38
33
39
val candidates: MutableList <IceCandidate > = mutableListOf ()
34
- val offerer =
40
+ offerer =
35
41
Offerer (
36
42
context,
37
43
queue,
@@ -55,6 +61,10 @@ class WebRTC(
55
61
},
56
62
)
57
63
64
+ couroutineScope.launch {
65
+ session.subscribe(config.topicOffererOnCandidate, ::candidateHandler).await()
66
+ }
67
+
58
68
val offer = offerer.createOffer(offerConfig)
59
69
Thread .sleep(200 )
60
70
@@ -95,13 +105,48 @@ class WebRTC(
95
105
val sdpString = descriptionMap.getString(" sdp" )
96
106
val sdpType = descriptionMap.getString(" type" )
97
107
98
- val remoteDescription =
99
- SessionDescription (SessionDescription .Type .fromCanonicalForm(sdpType), sdpString)
108
+ val remoteDescription = SessionDescription (SessionDescription .Type .fromCanonicalForm(sdpType), sdpString)
100
109
101
110
offerer.setRemoteDescription(remoteDescription)
102
111
103
- offerer.waitForDataChannelOpen ()
112
+ offerer.waitForDataChannelToOpen ()
104
113
105
114
return WebRTCSession (offerer.peerConnection!! , offerer.dataChannel!! )
106
115
}
116
+
117
+ private fun candidateHandler (event : Event ) {
118
+ if (event.args == null || event.args!! .size < 2 ) {
119
+ throw Exception (" invalid arguments length" )
120
+ }
121
+
122
+ val jsonString =
123
+ event.args?.get(1 ) as ? String
124
+ ? : throw Exception (" Invalid argument type: Second argument must be a JSON string" )
125
+
126
+ val result =
127
+ try {
128
+ convertJsonToMap(jsonString)
129
+ } catch (e: Exception ) {
130
+ throw Exception (" Invalid JSON: Unable to parse JSON string" )
131
+ }
132
+
133
+ val candidate =
134
+ result[" candidate" ] as ? String
135
+ ? : throw Exception (" Invalid candidate: 'candidate' field is missing or not a string" )
136
+
137
+ val sdpMLineIndex =
138
+ result[" sdpMLineIndex" ] as ? Int
139
+ ? : throw Exception (" Invalid sdpMLineIndex: 'sdpMLineIndex' field is missing or not an integer" )
140
+
141
+ val sdpMid =
142
+ result[" sdpMid" ] as ? String
143
+ ? : throw Exception (" Invalid sdpMid: 'sdpMid' field is missing or not a string" )
144
+
145
+ try {
146
+ val iceCandidate = IceCandidate (sdpMid, sdpMLineIndex, candidate)
147
+ offerer.addIceCandidate(iceCandidate)
148
+ } catch (e: Exception ) {
149
+ throw Exception (" Failed to add ICE candidate: ${e.message} " )
150
+ }
151
+ }
107
152
}
0 commit comments