@@ -23,7 +23,8 @@ defmodule ExWebRTC.SCTPTransport do
23
23
connected: false ,
24
24
id_type: nil ,
25
25
timer: nil ,
26
- channels: % { }
26
+ channels: % { } ,
27
+ stats: % { }
27
28
}
28
29
end
29
30
@@ -45,6 +46,24 @@ defmodule ExWebRTC.SCTPTransport do
45
46
sctp_transport . channels != % { }
46
47
end
47
48
49
+ @ spec get_stats ( t ( ) , non_neg_integer ( ) ) :: [ map ( ) ]
50
+ def get_stats ( sctp_transport , timestamp ) do
51
+ Enum . map ( sctp_transport . channels , fn { ref , channel } ->
52
+ stats = Map . fetch! ( sctp_transport . stats , ref )
53
+
54
+ % {
55
+ id: inspect ( channel . ref ) ,
56
+ type: :data_channel ,
57
+ timestamp: timestamp ,
58
+ data_channel_identifier: channel . id ,
59
+ label: channel . label ,
60
+ protocol: channel . protocol ,
61
+ state: channel . ready_state
62
+ }
63
+ |> Map . merge ( stats )
64
+ end )
65
+ end
66
+
48
67
@ spec add_channel (
49
68
t ( ) ,
50
69
String . t ( ) ,
@@ -67,7 +86,8 @@ defmodule ExWebRTC.SCTPTransport do
67
86
}
68
87
69
88
channels = Map . put ( sctp_transport . channels , channel . ref , channel )
70
- sctp_transport = % { sctp_transport | channels: channels }
89
+ stats = Map . put ( sctp_transport . stats , channel . ref , initial_stats ( ) )
90
+ sctp_transport = % { sctp_transport | channels: channels , stats: stats }
71
91
72
92
{ events , sctp_transport } =
73
93
if sctp_transport . connected do
@@ -90,7 +110,8 @@ defmodule ExWebRTC.SCTPTransport do
90
110
{ [ ] , sctp_transport }
91
111
92
112
{ % DataChannel { id: id } , channels } ->
93
- sctp_transport = % { sctp_transport | channels: channels }
113
+ stats = Map . delete ( sctp_transport . stats , ref )
114
+ sctp_transport = % { sctp_transport | channels: channels , stats: stats }
94
115
95
116
{ events , sctp_transport } =
96
117
if id != nil do
@@ -114,8 +135,9 @@ defmodule ExWebRTC.SCTPTransport do
114
135
115
136
case Map . fetch ( sctp_transport . channels , ref ) do
116
137
{ :ok , % DataChannel { ready_state: :open , id: id } } when id != nil ->
138
+ stats = update_stats ( sctp_transport . stats , ref , data , :sent )
117
139
:ok = ExSCTP . send ( sctp_transport . ref , id , ppi , data )
118
- handle_events ( sctp_transport )
140
+ handle_events ( % { sctp_transport | stats: stats } )
119
141
120
142
{ :ok , % DataChannel { id: id } } ->
121
143
Logger . warning (
@@ -207,8 +229,9 @@ defmodule ExWebRTC.SCTPTransport do
207
229
case Enum . find ( sctp_transport . channels , fn { _k , v } -> v . id == id end ) do
208
230
{ ref , % DataChannel { ref: ref } } ->
209
231
channels = Map . delete ( sctp_transport . channels , ref )
232
+ stats = Map . delete ( sctp_transport . stats , ref )
210
233
event = { :state_change , ref , :closed }
211
- { event , % { sctp_transport | channels: channels } }
234
+ { event , % { sctp_transport | channels: channels , stats: stats } }
212
235
213
236
_other ->
214
237
{ nil , sctp_transport }
@@ -257,7 +280,9 @@ defmodule ExWebRTC.SCTPTransport do
257
280
case Enum . find_value ( sctp_transport . channels , fn { _k , v } -> v . id == id end ) do
258
281
{ ref , % DataChannel { } } ->
259
282
channels = Map . delete ( sctp_transport . channels , ref )
260
- { { :state_change , ref , :closed } , % { sctp_transport | channels: channels } }
283
+ stats = Map . delete ( sctp_transport . stats , ref )
284
+ sctp_transport = % { sctp_transport | channels: channels , stats: stats }
285
+ { { :state_change , ref , :closed } , sctp_transport }
261
286
262
287
nil ->
263
288
{ nil , sctp_transport }
@@ -269,7 +294,8 @@ defmodule ExWebRTC.SCTPTransport do
269
294
with { :ok , data } <- from_raw_data ( data , ppi ) ,
270
295
{ ref , % DataChannel { ready_state: :open } } <-
271
296
Enum . find ( sctp_transport . channels , fn { _k , v } -> v . id == id end ) do
272
- { { :data , ref , data } , sctp_transport }
297
+ stats = update_stats ( sctp_transport . stats , ref , data , :received )
298
+ { { :data , ref , data } , % { sctp_transport | stats: stats } }
273
299
else
274
300
{ _ref , % DataChannel { } } ->
275
301
Logger . warning ( "Received data on DataChannel with id #{ id } that is not open. Discarding" )
@@ -309,7 +335,8 @@ defmodule ExWebRTC.SCTPTransport do
309
335
# In theory, we should also send the :open event here (W3C 6.2.3)
310
336
# TODO
311
337
channels = Map . put ( sctp_transport . channels , channel . ref , channel )
312
- sctp_transport = % { sctp_transport | channels: channels }
338
+ stats = Map . put ( sctp_transport . stats , channel . ref , initial_stats ( ) )
339
+ sctp_transport = % { sctp_transport | channels: channels , stats: stats }
313
340
314
341
case ExSCTP . configure_stream (
315
342
sctp_transport . ref ,
@@ -396,4 +423,31 @@ defmodule ExWebRTC.SCTPTransport do
396
423
{ :odd , 1 } -> max_id + 2
397
424
end
398
425
end
426
+
427
+ defp initial_stats ( ) do
428
+ % {
429
+ messages_sent: 0 ,
430
+ messages_received: 0 ,
431
+ bytes_sent: 0 ,
432
+ bytes_received: 0
433
+ }
434
+ end
435
+
436
+ defp update_stats ( stats , ref , data , type ) do
437
+ Map . update! ( stats , ref , fn stat ->
438
+ if type == :sent do
439
+ % {
440
+ stat
441
+ | messages_sent: stat . messages_sent + 1 ,
442
+ bytes_sent: stat . bytes_sent + byte_size ( data )
443
+ }
444
+ else
445
+ % {
446
+ stat
447
+ | messages_received: stat . messages_received + 1 ,
448
+ bytes_received: stat . bytes_received + byte_size ( data )
449
+ }
450
+ end
451
+ end )
452
+ end
399
453
end
0 commit comments