This repository has been archived by the owner on Mar 16, 2022. It is now read-only.
forked from pion/webrtc
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
179 lines (142 loc) · 3.61 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// +build quic
package main
import (
"flag"
"fmt"
"time"
"github.com/pion/quic"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/examples/internal/signal"
)
const messageSize = 15
func main() {
isOffer := flag.Bool("offer", false, "Act as the offerer if set")
flag.Parse()
// This example shows off the experimental implementation of webrtc-quic.
// Everything below is the Pion WebRTC (ORTC) API! Thanks for using it ❤️.
// Create an API object
api := webrtc.NewAPI()
// Prepare ICE gathering options
iceOptions := webrtc.ICEGatherOptions{
ICEServers: []webrtc.ICEServer{
{URLs: []string{"stun:stun.l.google.com:19302"}},
},
}
// Create the ICE gatherer
gatherer, err := api.NewICEGatherer(iceOptions)
if err != nil {
panic(err)
}
// Construct the ICE transport
ice := api.NewICETransport(gatherer)
// Construct the Quic transport
qt, err := api.NewQUICTransport(ice, nil)
if err != nil {
panic(err)
}
// Handle incoming streams
qt.OnBidirectionalStream(func(stream *quic.BidirectionalStream) {
fmt.Printf("New stream %d\n", stream.StreamID())
// Handle reading from the stream
go ReadLoop(stream)
// Handle writing to the stream
go WriteLoop(stream)
})
gatherFinished := make(chan struct{})
gatherer.OnLocalCandidate(func(i *webrtc.ICECandidate) {
if i == nil {
close(gatherFinished)
}
})
// Gather candidates
err = gatherer.Gather()
if err != nil {
panic(err)
}
<-gatherFinished
iceCandidates, err := gatherer.GetLocalCandidates()
if err != nil {
panic(err)
}
iceParams, err := gatherer.GetLocalParameters()
if err != nil {
panic(err)
}
quicParams, err := qt.GetLocalParameters()
if err != nil {
panic(err)
}
s := Signal{
ICECandidates: iceCandidates,
ICEParameters: iceParams,
QuicParameters: quicParams,
}
// Exchange the information
fmt.Println(signal.Encode(s))
remoteSignal := Signal{}
signal.Decode(signal.MustReadStdin(), &remoteSignal)
iceRole := webrtc.ICERoleControlled
if *isOffer {
iceRole = webrtc.ICERoleControlling
}
err = ice.SetRemoteCandidates(remoteSignal.ICECandidates)
if err != nil {
panic(err)
}
// Start the ICE transport
err = ice.Start(nil, remoteSignal.ICEParameters, &iceRole)
if err != nil {
panic(err)
}
// Start the Quic transport
err = qt.Start(remoteSignal.QuicParameters)
if err != nil {
panic(err)
}
// Construct the stream as the offerer
if *isOffer {
var stream *quic.BidirectionalStream
stream, err = qt.CreateBidirectionalStream()
if err != nil {
panic(err)
}
// Handle reading from the stream
go ReadLoop(stream)
// Handle writing to the stream
go WriteLoop(stream)
}
select {}
}
// Signal is used to exchange signaling info.
// This is not part of the ORTC spec. You are free
// to exchange this information any way you want.
type Signal struct {
ICECandidates []webrtc.ICECandidate `json:"iceCandidates"`
ICEParameters webrtc.ICEParameters `json:"iceParameters"`
QuicParameters webrtc.QUICParameters `json:"quicParameters"`
}
// ReadLoop reads from the stream
func ReadLoop(s *quic.BidirectionalStream) {
for {
buffer := make([]byte, messageSize)
params, err := s.ReadInto(buffer)
if err != nil {
panic(err)
}
fmt.Printf("Message from stream '%d': %s\n", s.StreamID(), string(buffer[:params.Amount]))
}
}
// WriteLoop writes to the stream
func WriteLoop(s *quic.BidirectionalStream) {
for range time.NewTicker(5 * time.Second).C {
message := signal.RandSeq(messageSize)
fmt.Printf("Sending %s \n", message)
data := quic.StreamWriteParameters{
Data: []byte(message),
}
err := s.Write(data)
if err != nil {
panic(err)
}
}
}