github.com/pion/webrtc/v3@v3.2.24/examples/data-channels/main.go (about) 1 // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly> 2 // SPDX-License-Identifier: MIT 3 4 // data-channels is a Pion WebRTC application that shows how you can send/recv DataChannel messages from a web browser 5 package main 6 7 import ( 8 "fmt" 9 "os" 10 "time" 11 12 "github.com/pion/webrtc/v3" 13 "github.com/pion/webrtc/v3/examples/internal/signal" 14 ) 15 16 func main() { 17 // Everything below is the Pion WebRTC API! Thanks for using it ❤️. 18 19 // Prepare the configuration 20 config := webrtc.Configuration{ 21 ICEServers: []webrtc.ICEServer{ 22 { 23 URLs: []string{"stun:stun.l.google.com:19302"}, 24 }, 25 }, 26 } 27 28 // Create a new RTCPeerConnection 29 peerConnection, err := webrtc.NewPeerConnection(config) 30 if err != nil { 31 panic(err) 32 } 33 defer func() { 34 if cErr := peerConnection.Close(); cErr != nil { 35 fmt.Printf("cannot close peerConnection: %v\n", cErr) 36 } 37 }() 38 39 // Set the handler for Peer connection state 40 // This will notify you when the peer has connected/disconnected 41 peerConnection.OnConnectionStateChange(func(s webrtc.PeerConnectionState) { 42 fmt.Printf("Peer Connection State has changed: %s\n", s.String()) 43 44 if s == webrtc.PeerConnectionStateFailed { 45 // Wait until PeerConnection has had no network activity for 30 seconds or another failure. It may be reconnected using an ICE Restart. 46 // Use webrtc.PeerConnectionStateDisconnected if you are interested in detecting faster timeout. 47 // Note that the PeerConnection may come back from PeerConnectionStateDisconnected. 48 fmt.Println("Peer Connection has gone to failed exiting") 49 os.Exit(0) 50 } 51 }) 52 53 // Register data channel creation handling 54 peerConnection.OnDataChannel(func(d *webrtc.DataChannel) { 55 fmt.Printf("New DataChannel %s %d\n", d.Label(), d.ID()) 56 57 // Register channel opening handling 58 d.OnOpen(func() { 59 fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", d.Label(), d.ID()) 60 61 for range time.NewTicker(5 * time.Second).C { 62 message := signal.RandSeq(15) 63 fmt.Printf("Sending '%s'\n", message) 64 65 // Send the message as text 66 sendErr := d.SendText(message) 67 if sendErr != nil { 68 panic(sendErr) 69 } 70 } 71 }) 72 73 // Register text message handling 74 d.OnMessage(func(msg webrtc.DataChannelMessage) { 75 fmt.Printf("Message from DataChannel '%s': '%s'\n", d.Label(), string(msg.Data)) 76 }) 77 }) 78 79 // Wait for the offer to be pasted 80 offer := webrtc.SessionDescription{} 81 signal.Decode(signal.MustReadStdin(), &offer) 82 83 // Set the remote SessionDescription 84 err = peerConnection.SetRemoteDescription(offer) 85 if err != nil { 86 panic(err) 87 } 88 89 // Create an answer 90 answer, err := peerConnection.CreateAnswer(nil) 91 if err != nil { 92 panic(err) 93 } 94 95 // Create channel that is blocked until ICE Gathering is complete 96 gatherComplete := webrtc.GatheringCompletePromise(peerConnection) 97 98 // Sets the LocalDescription, and starts our UDP listeners 99 err = peerConnection.SetLocalDescription(answer) 100 if err != nil { 101 panic(err) 102 } 103 104 // Block until ICE Gathering is complete, disabling trickle ICE 105 // we do this because we only can exchange one signaling message 106 // in a production application you should exchange ICE Candidates via OnICECandidate 107 <-gatherComplete 108 109 // Output the answer in base64 so we can paste it in browser 110 fmt.Println(signal.Encode(*peerConnection.LocalDescription())) 111 112 // Block forever 113 select {} 114 }