Skip to content

Commit 4ee3747

Browse files
authored
Implement DataChannel OnError/OnClosing for WASM
`OnClosing` is only implemented in WASM at this time. `OnError` isn't tested, but should work as follows the existing code. Relates to #479 Relates to #519
1 parent 59c7270 commit 4ee3747

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

datachannel_js.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package webrtc
88

99
import (
10+
"errors"
1011
"fmt"
1112
"syscall/js"
1213

@@ -26,8 +27,10 @@ type DataChannel struct {
2627
// syscall/js API. Initially nil.
2728
onOpenHandler *js.Func
2829
onCloseHandler *js.Func
30+
onClosingHandler *js.Func
2931
onMessageHandler *js.Func
3032
onBufferedAmountLow *js.Func
33+
onErrorHandler *js.Func
3134

3235
// A reference to the associated api object used by this datachannel
3336
api *API
@@ -63,6 +66,39 @@ func (d *DataChannel) OnClose(f func()) {
6366
d.underlying.Set("onclose", onCloseHandler)
6467
}
6568

69+
// FYI `OnClosing` is not implemented in the non-JS version of Pion.
70+
71+
func (d *DataChannel) OnClosing(f func()) {
72+
if d.onClosingHandler != nil {
73+
oldHandler := d.onClosingHandler
74+
defer oldHandler.Release()
75+
}
76+
onClosingHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
77+
go f()
78+
return js.Undefined()
79+
})
80+
d.onClosingHandler = &onClosingHandler
81+
d.underlying.Set("onclosing", onClosingHandler)
82+
}
83+
84+
func (d *DataChannel) OnError(f func(err error)) {
85+
if d.onErrorHandler != nil {
86+
oldHandler := d.onErrorHandler
87+
defer oldHandler.Release()
88+
}
89+
onErrorHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
90+
event := args[0]
91+
errorObj := event.Get("error")
92+
// FYI RTCError has some extra properties, e.g. `errorDetail`:
93+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/error_event
94+
errorMessage := errorObj.Get("message").String()
95+
go f(errors.New(errorMessage))
96+
return js.Undefined()
97+
})
98+
d.onErrorHandler = &onErrorHandler
99+
d.underlying.Set("onerror", onErrorHandler)
100+
}
101+
66102
// OnMessage sets an event handler which is invoked on a binary message arrival
67103
// from a remote peer. Note that browsers may place limitations on message size.
68104
func (d *DataChannel) OnMessage(f func(msg DataChannelMessage)) {
@@ -145,12 +181,18 @@ func (d *DataChannel) Close() (err error) {
145181
if d.onCloseHandler != nil {
146182
d.onCloseHandler.Release()
147183
}
184+
if d.onClosingHandler != nil {
185+
d.onClosingHandler.Release()
186+
}
148187
if d.onMessageHandler != nil {
149188
d.onMessageHandler.Release()
150189
}
151190
if d.onBufferedAmountLow != nil {
152191
d.onBufferedAmountLow.Release()
153192
}
193+
if d.onErrorHandler != nil {
194+
d.onErrorHandler.Release()
195+
}
154196

155197
return nil
156198
}

examples/data-channels/jsfiddle/main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ func main() {
4242
sendChannel.OnClose(func() {
4343
fmt.Println("sendChannel has closed")
4444
})
45+
sendChannel.OnClosing(func() {
46+
fmt.Println("sendChannel is closing")
47+
})
48+
sendChannel.OnError(func(err error) {
49+
fmt.Println("sendChannel error", err)
50+
})
4551
sendChannel.OnOpen(func() {
4652
fmt.Println("sendChannel has opened")
4753

0 commit comments

Comments
 (0)