@@ -14,6 +14,7 @@ import (
14
14
"runtime"
15
15
"strings"
16
16
"sync"
17
+ "text/tabwriter"
17
18
"time"
18
19
19
20
"github.com/dchest/uniuri"
@@ -41,6 +42,15 @@ type LiveOffer struct {
41
42
p * peers.Peer
42
43
id string
43
44
}
45
+ type CandidatePairValues struct {
46
+ FP string `json:"fp"`
47
+ LocalAddr string `json:"local_addr"` // IP:Port
48
+ LocalProtocol string `json:"local_proto"`
49
+ LocalType string `json:"local_type"`
50
+ RemoteAddr string `json:"remote_addr"`
51
+ RemoteProtocol string `json:"remote_proto"`
52
+ RemoteType string `json:"remote_type"`
53
+ }
44
54
45
55
const socketFileName = "webexec.sock"
46
56
@@ -194,19 +204,63 @@ func StartSocketServer(lc fx.Lifecycle, s *sockServer, params SocketStartParams)
194
204
}
195
205
196
206
func (s * sockServer ) handleStatus (w http.ResponseWriter , r * http.Request ) {
197
- if r .Method == "GET" {
198
- w .Write ([]byte ("READY" ))
207
+ Logger .Info ("Got status request" )
208
+ if r .Method != "GET" {
209
+ http .Error (w , "Method not allowed" , http .StatusMethodNotAllowed )
210
+ return
199
211
}
200
- /* TODO: return status of all connected peers
201
212
if len (peers .Peers ) == 0 {
202
213
fmt .Println ("No peers connected" )
203
- } else {
204
- fmt.Println("Connected peers:")
205
- for _, peer := range peers.Peers {
206
- fmt.Printf(" %s", peer.FP)
214
+ return
215
+ }
216
+ var ret []CandidatePairValues
217
+ fmt .Println ("Connected peers:" )
218
+ for _ , peer := range peers .Peers {
219
+ if peer .PC == nil {
220
+ continue
207
221
}
222
+ stats := peer .PC .GetStats ()
223
+ for _ , report := range stats {
224
+ pairStats , ok := report .(webrtc.ICECandidatePairStats )
225
+ if ! ok || pairStats .Type != webrtc .StatsTypeCandidatePair {
226
+ continue
227
+ }
228
+ // check if it is selected
229
+ if pairStats .State != webrtc .StatsICECandidatePairStateSucceeded {
230
+ continue
231
+ }
232
+ local , ok := stats [pairStats .LocalCandidateID ].(webrtc.ICECandidateStats )
233
+ if ! ok {
234
+ http .Error (w , "Failed to get local candidate" , http .StatusInternalServerError )
235
+ return
236
+ }
237
+ remote , ok := stats [pairStats .RemoteCandidateID ].(webrtc.ICECandidateStats )
238
+ if ! ok {
239
+ http .Error (w , "Failed to get remote candidate" , http .StatusInternalServerError )
240
+ return
241
+ }
242
+ ret = append (ret , CandidatePairValues {
243
+ FP : peer .FP ,
244
+ LocalAddr : fmt .Sprintf ("%s:%d" , local .IP , local .Port ),
245
+ LocalProtocol : local .Protocol ,
246
+ LocalType : local .CandidateType .String (),
247
+ RemoteAddr : fmt .Sprintf ("%s:%d" , remote .IP , remote .Port ),
248
+ RemoteProtocol : remote .Protocol ,
249
+ RemoteType : remote .CandidateType .String (),
250
+ })
251
+ break
252
+ }
253
+ }
254
+ if ret == nil {
255
+ // no peers are connected, return an empty response
256
+ ret = []CandidatePairValues {}
257
+ }
258
+ b , err := json .Marshal (ret )
259
+ if err != nil {
260
+ http .Error (w , "Failed to marshal response" , http .StatusInternalServerError )
261
+ return
208
262
}
209
- */
263
+ w . Write ( b )
210
264
}
211
265
func (s * sockServer ) handleLayout (w http.ResponseWriter , r * http.Request ) {
212
266
if r .Method == "GET" {
@@ -401,3 +455,13 @@ func writeClipboard(data []byte, mimeType string) error {
401
455
}
402
456
return cmd .Wait ()
403
457
}
458
+
459
+ // const ELLIPSIS = "\uf141"
460
+ func writeICEPairsHeader (w * tabwriter.Writer ) {
461
+ fmt .Fprintln (w , "Finger\uf141 \t Addr\t Protocol\t Type\t \uf141 \t Addr\t Protocol\t Type" )
462
+ }
463
+ func (p * CandidatePairValues ) Write (w * tabwriter.Writer ) {
464
+ fp := fmt .Sprintf ("%s\uf141 " , string ([]rune (p .FP )[:6 ]))
465
+ fmt .Fprintln (w , strings .Join ([]string {fp , p .LocalAddr , p .LocalProtocol ,
466
+ p .LocalType , "->" , p .RemoteAddr , p .RemoteProtocol , p .RemoteType }, "\t " ))
467
+ }
0 commit comments