mirror of
https://github.com/pion/webrtc.git
synced 2025-10-05 07:06:51 +08:00

Add OnICECandidate and OnICEGatheringStateChange methods to PeerConnection. The main goal of this change is to improve API compatibility with the JavaScript/Wasm bindings. It does not actually add trickle ICE support or change the ICE candidate gathering process, which is still synchronous in the Go implementation. Rather, it fires the appropriate events similar to they way they would be fired in a true trickle ICE process. Remove unused OnNegotiationNeeded event handler. This handler is not required for most applications and would be difficult to implement in Go. This commit removes the handler from the JavaScript/Wasm bindings, which leads to a more similar API for Go and JavaScript/Wasm. Add OnICEGatheringStateChange to the JavaScript/Wasm bindings. Also changes the Go implementation so that the function signatures match.
113 lines
2.6 KiB
Go
113 lines
2.6 KiB
Go
// +build js,wasm
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"syscall/js"
|
|
|
|
"github.com/pions/webrtc"
|
|
"github.com/pions/webrtc/examples/internal/signal"
|
|
)
|
|
|
|
func main() {
|
|
// Configure and create a new PeerConnection.
|
|
config := webrtc.Configuration{
|
|
ICEServers: []webrtc.ICEServer{
|
|
{
|
|
URLs: []string{"stun:stun.l.google.com:19302"},
|
|
},
|
|
},
|
|
}
|
|
pc, err := webrtc.NewPeerConnection(config)
|
|
if err != nil {
|
|
handleError(err)
|
|
}
|
|
|
|
// Create DataChannel.
|
|
sendChannel, err := pc.CreateDataChannel("foo", nil)
|
|
if err != nil {
|
|
handleError(err)
|
|
}
|
|
sendChannel.OnClose(func() {
|
|
fmt.Println("sendChannel has closed")
|
|
})
|
|
sendChannel.OnOpen(func() {
|
|
fmt.Println("sendChannel has opened")
|
|
})
|
|
sendChannel.OnMessage(func(msg webrtc.DataChannelMessage) {
|
|
log(fmt.Sprintf("Message from DataChannel %s payload %s", sendChannel.Label(), string(msg.Data)))
|
|
})
|
|
|
|
// Create offer
|
|
offer, err := pc.CreateOffer(nil)
|
|
if err != nil {
|
|
handleError(err)
|
|
}
|
|
if err := pc.SetLocalDescription(offer); err != nil {
|
|
handleError(err)
|
|
}
|
|
|
|
// Add handlers for setting up the connection.
|
|
pc.OnICEConnectionStateChange(func(state webrtc.ICEConnectionState) {
|
|
log(fmt.Sprint(state))
|
|
})
|
|
pc.OnICECandidate(func(candidate *webrtc.ICECandidate) {
|
|
if candidate != nil {
|
|
encodedDescr := signal.Encode(pc.LocalDescription())
|
|
el := getElementByID("localSessionDescription")
|
|
el.Set("value", encodedDescr)
|
|
}
|
|
})
|
|
|
|
// Set up global callbacks which will be triggered on button clicks.
|
|
js.Global().Set("sendMessage", js.FuncOf(func(_ js.Value, _ []js.Value) interface{} {
|
|
go func() {
|
|
el := getElementByID("message")
|
|
message := el.Get("value").String()
|
|
if message == "" {
|
|
js.Global().Call("alert", "Message must not be empty")
|
|
return
|
|
}
|
|
if err := sendChannel.SendText(message); err != nil {
|
|
handleError(err)
|
|
}
|
|
}()
|
|
return js.Undefined()
|
|
}))
|
|
js.Global().Set("startSession", js.FuncOf(func(_ js.Value, _ []js.Value) interface{} {
|
|
go func() {
|
|
el := getElementByID("remoteSessionDescription")
|
|
sd := el.Get("value").String()
|
|
if sd == "" {
|
|
js.Global().Call("alert", "Session Description must not be empty")
|
|
return
|
|
}
|
|
|
|
descr := webrtc.SessionDescription{}
|
|
signal.Decode(sd, &descr)
|
|
if err := pc.SetRemoteDescription(descr); err != nil {
|
|
handleError(err)
|
|
}
|
|
}()
|
|
return js.Undefined()
|
|
}))
|
|
|
|
// Stay alive
|
|
select {}
|
|
}
|
|
|
|
func log(msg string) {
|
|
el := getElementByID("logs")
|
|
el.Set("innerHTML", el.Get("innerHTML").String()+msg+"<br>")
|
|
}
|
|
|
|
func handleError(err error) {
|
|
log("Unexpected error. Check console.")
|
|
panic(err)
|
|
}
|
|
|
|
func getElementByID(id string) js.Value {
|
|
return js.Global().Get("document").Call("getElementById", id)
|
|
}
|