forked from pion/webrtc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
132 lines (104 loc) · 3.43 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package main
import (
"encoding/json"
"flag"
"fmt"
"math/rand"
"net/http"
"time"
"github.com/pions/webrtc"
"github.com/pions/webrtc/pkg/datachannel"
"github.com/pions/webrtc/pkg/ice"
)
func main() {
addr := flag.String("address", ":50000", "Address to host the HTTP server on.")
flag.Parse()
offerChan, answerChan := mustSignalViaHTTP(*addr)
/* Everything below is the pion-WebRTC API, thanks for using it! */
// Prepare the configuration
config := webrtc.RTCConfiguration{
IceServers: []webrtc.RTCIceServer{
{
URLs: []string{"stun:stun.l.google.com:19302"},
},
},
}
// Create a new RTCPeerConnection
peerConnection, err := webrtc.New(config)
check(err)
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
peerConnection.OnICEConnectionStateChange = func(connectionState ice.ConnectionState) {
fmt.Printf("ICE Connection State has changed: %s\n", connectionState.String())
}
// Register data channel creation handling
peerConnection.OnDataChannel = func(d *webrtc.RTCDataChannel) {
fmt.Printf("New DataChannel %s %d\n", d.Label, d.ID)
d.Lock()
defer d.Unlock()
// Register channel opening handling
d.OnOpen = func() {
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)
for range time.NewTicker(5 * time.Second).C {
message := randSeq(15)
fmt.Printf("Sending %s \n", message)
err := d.Send(datachannel.PayloadString{Data: []byte(message)})
check(err)
}
}
// Register message handling
d.Onmessage = func(payload datachannel.Payload) {
switch p := payload.(type) {
case *datachannel.PayloadString:
fmt.Printf("Message '%s' from DataChannel '%s' payload '%s'\n", p.PayloadType().String(), d.Label, string(p.Data))
case *datachannel.PayloadBinary:
fmt.Printf("Message '%s' from DataChannel '%s' payload '% 02x'\n", p.PayloadType().String(), d.Label, p.Data)
default:
fmt.Printf("Message '%s' from DataChannel '%s' no payload \n", p.PayloadType().String(), d.Label)
}
}
}
// Wait for the remote SessionDescription
offer := <-offerChan
err = peerConnection.SetRemoteDescription(offer)
check(err)
// Sets the LocalDescription, and starts our UDP listeners
answer, err := peerConnection.CreateAnswer(nil)
check(err)
// Send the answer
answerChan <- answer
// Block forever
select {}
}
// mustSignalViaHTTP exchange the SDP offer and answer using an HTTP server.
func mustSignalViaHTTP(address string) (offerOut chan webrtc.RTCSessionDescription, answerIn chan webrtc.RTCSessionDescription) {
offerOut = make(chan webrtc.RTCSessionDescription)
answerIn = make(chan webrtc.RTCSessionDescription)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
var offer webrtc.RTCSessionDescription
err := json.NewDecoder(r.Body).Decode(&offer)
check(err)
offerOut <- offer
answer := <-answerIn
err = json.NewEncoder(w).Encode(answer)
check(err)
})
go http.ListenAndServe(address, nil)
fmt.Println("Listening on", address)
return
}
func randSeq(n int) string {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
b := make([]rune, n)
for i := range b {
b[i] = letters[r.Intn(len(letters))]
}
return string(b)
}
// check is used to panic in an error occurs.
func check(err error) {
if err != nil {
panic(err)
}
}