| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
- // SPDX-License-Identifier: MIT
- //go:build !js
- // +build !js
- // ice-single-port demonstrates Pion WebRTC's ability to serve many PeerConnections on a single port.
- package main
- import (
- "encoding/json"
- "fmt"
- "net/http"
- "time"
- "github.com/pion/ice/v2"
- "github.com/pion/webrtc/v3"
- )
- var api *webrtc.API //nolint
- // Everything below is the Pion WebRTC API! Thanks for using it ❤️.
- func doSignaling(w http.ResponseWriter, r *http.Request) {
- peerConnection, err := api.NewPeerConnection(webrtc.Configuration{})
- if err != nil {
- panic(err)
- }
- // Set the handler for ICE connection state
- // This will notify you when the peer has connected/disconnected
- peerConnection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) {
- fmt.Printf("ICE Connection State has changed: %s\n", connectionState.String())
- })
- // Send the current time via a DataChannel to the remote peer every 3 seconds
- peerConnection.OnDataChannel(func(d *webrtc.DataChannel) {
- d.OnOpen(func() {
- for range time.Tick(time.Second * 3) {
- if err = d.SendText(time.Now().String()); err != nil {
- panic(err)
- }
- }
- })
- })
- var offer webrtc.SessionDescription
- if err = json.NewDecoder(r.Body).Decode(&offer); err != nil {
- panic(err)
- }
- if err = peerConnection.SetRemoteDescription(offer); err != nil {
- panic(err)
- }
- // Create channel that is blocked until ICE Gathering is complete
- gatherComplete := webrtc.GatheringCompletePromise(peerConnection)
- answer, err := peerConnection.CreateAnswer(nil)
- if err != nil {
- panic(err)
- } else if err = peerConnection.SetLocalDescription(answer); err != nil {
- panic(err)
- }
- // Block until ICE Gathering is complete, disabling trickle ICE
- // we do this because we only can exchange one signaling message
- // in a production application you should exchange ICE Candidates via OnICECandidate
- <-gatherComplete
- response, err := json.Marshal(*peerConnection.LocalDescription())
- if err != nil {
- panic(err)
- }
- w.Header().Set("Content-Type", "application/json")
- if _, err := w.Write(response); err != nil {
- panic(err)
- }
- }
- func main() {
- // Create a SettingEngine, this allows non-standard WebRTC behavior
- settingEngine := webrtc.SettingEngine{}
- // Configure our SettingEngine to use our UDPMux. By default a PeerConnection has
- // no global state. The API+SettingEngine allows the user to share state between them.
- // In this case we are sharing our listening port across many.
- // Listen on UDP Port 8443, will be used for all WebRTC traffic
- mux, err := ice.NewMultiUDPMuxFromPort(8443)
- if err != nil {
- panic(err)
- }
- fmt.Printf("Listening for WebRTC traffic at %d\n", 8443)
- settingEngine.SetICEUDPMux(mux)
- // Create a new API using our SettingEngine
- api = webrtc.NewAPI(webrtc.WithSettingEngine(settingEngine))
- http.Handle("/", http.FileServer(http.Dir(".")))
- http.HandleFunc("/doSignaling", doSignaling)
- fmt.Println("Open http://localhost:8080 to access this demo")
- // nolint: gosec
- panic(http.ListenAndServe(":8080", nil))
- }
|