Skip to content

Commit fdf1d6e

Browse files
committed
Add built-in turn server.
1 parent 4a6100a commit fdf1d6e

File tree

6 files changed

+145
-16
lines changed

6 files changed

+145
-16
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ go 1.12
55
require (
66
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9
77
github.com/gorilla/websocket v1.4.1
8+
github.com/pion/turn/v2 v2.0.1
89
github.com/rs/zerolog v1.14.3
910
)

go.sum

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
11
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 h1:xz6Nv3zcwO2Lila35hcb0QloCQsc38Al13RNEzWRpX4=
22
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9/go.mod h1:2wSM9zJkl1UQEFZgSd68NfCgRz1VL1jzy/RjCg+ULrs=
33
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
4+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
45
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
56
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
7+
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
8+
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
9+
github.com/pion/stun v0.3.3 h1:brYuPl9bN9w/VM7OdNzRSLoqsnwlyNvD9MVeJrHjDQw=
10+
github.com/pion/stun v0.3.3/go.mod h1:xrCld6XM+6GWDZdvjPlLMsTU21rNxnO6UO8XsAvHr/M=
11+
github.com/pion/transport v0.8.10 h1:lTiobMEw2PG6BH/mgIVqTV2mBp/mPT+IJLaN8ZxgdHk=
12+
github.com/pion/transport v0.8.10/go.mod h1:tBmha/UCjpum5hqTWhfAEs3CO4/tHSg0MYRhSzR+CZ8=
13+
github.com/pion/turn/v2 v2.0.1 h1:TO6NsNCqSIrhk33Eg3l7+KPeUOjLY3Ff70l+DAxAQOQ=
14+
github.com/pion/turn/v2 v2.0.1/go.mod h1:kl1hmT3NxcLynpXVnwJgObL8C9NaCyPTeqI2DcCpSZs=
615
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
16+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
717
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
818
github.com/rs/zerolog v1.14.3 h1:4EGfSkR2hJDB0s3oFfrlPqjU1e4WLncergLil3nEKW0=
919
github.com/rs/zerolog v1.14.3/go.mod h1:3WXPzbXEEliJ+a6UFE4vhIxV8qR1EML6ngzP9ug4eYg=
20+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
21+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
1022
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
1123
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
1224
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
1325
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
1426
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
1527
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
1628
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
29+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
30+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

main/server/main.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,25 @@ package main
22

33
import (
44
"github.com/cloudwebrtc/flutter-webrtc-server/pkg/signaler"
5+
"github.com/cloudwebrtc/flutter-webrtc-server/pkg/turn"
56
"github.com/cloudwebrtc/flutter-webrtc-server/pkg/websocket"
67
)
78

89
func main() {
9-
signaler := signaler.NewSignaler()
10-
wsServer := websocket.NewWebSocketServer(signaler.HandleNewWebSocket)
10+
turnConfig := turn.DefaultConfig()
11+
turnConfig.PublicIP = "123.45.67.89"
12+
turnConfig.Port = 19302
13+
turnConfig.Realm = "flutter-webrtc"
14+
turn := turn.NewTurnServer(turnConfig)
15+
16+
signaler := signaler.NewSignaler(turn)
17+
wsServer := websocket.NewWebSocketServer(signaler.HandleNewWebSocket, signaler.HandleTurnServerCredentials)
18+
1119
config := websocket.DefaultConfig()
1220
config.Port = 4443
1321
config.CertFile = "certs/cert.pem"
1422
config.KeyFile = "certs/key.pem"
1523
config.HTMLRoot = "html"
24+
1625
wsServer.Bind(config)
1726
}

pkg/signaler/signaler.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ package signaler
22

33
import (
44
"encoding/json"
5+
"net"
56
"net/http"
67
"strings"
78

89
"github.com/cloudwebrtc/flutter-webrtc-server/pkg/logger"
910
"github.com/cloudwebrtc/flutter-webrtc-server/pkg/transport"
11+
"github.com/cloudwebrtc/flutter-webrtc-server/pkg/turn"
1012
)
1113

1214
func Marshal(m map[string]interface{}) string {
@@ -50,16 +52,24 @@ type Session struct {
5052
type Signaler struct {
5153
peers map[string]Peer
5254
sessions map[string]Session
55+
turn *turn.TurnServer
5356
}
5457

55-
func NewSignaler() *Signaler {
58+
func NewSignaler(turn *turn.TurnServer) *Signaler {
5659
var signaler = &Signaler{
5760
peers: make(map[string]Peer),
5861
sessions: make(map[string]Session),
62+
turn: turn,
5963
}
64+
signaler.turn.AuthHandler = signaler.authHandler
6065
return signaler
6166
}
6267

68+
func (s Signaler) authHandler(username string, realm string, srcAddr net.Addr) ([]byte, bool) {
69+
// handle turn auth info.
70+
return nil, false
71+
}
72+
6373
func (s *Signaler) NotifyPeersUpdate(transport *transport.WebSocketTransport, peers map[string]Peer) {
6474
infos := []PeerInfo{}
6575
for _, peer := range peers {
@@ -73,6 +83,10 @@ func (s *Signaler) NotifyPeersUpdate(transport *transport.WebSocketTransport, pe
7383
}
7484
}
7585

86+
func (s *Signaler) HandleTurnServerCredentials(writer http.ResponseWriter, request *http.Request) {
87+
// return turn credentials for client.
88+
}
89+
7690
func (s *Signaler) HandleNewWebSocket(transport *transport.WebSocketTransport, request *http.Request) {
7791
logger.Infof("On Open %v", request)
7892
transport.On("message", func(message []byte) {

pkg/turn/turn.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package turn
2+
3+
import (
4+
"net"
5+
"strconv"
6+
7+
"github.com/cloudwebrtc/flutter-webrtc-server/pkg/logger"
8+
"github.com/pion/turn/v2"
9+
)
10+
11+
type TurnServerConfig struct {
12+
PublicIP string
13+
Port int
14+
Realm string
15+
}
16+
17+
func DefaultConfig() TurnServerConfig {
18+
return TurnServerConfig{
19+
PublicIP: "127.0.0.1",
20+
Port: 19302,
21+
Realm: "flutter-webrtc",
22+
}
23+
}
24+
25+
/*
26+
if key, ok := usersMap[username]; ok {
27+
return key, true
28+
}
29+
return nil, false
30+
*/
31+
32+
type TurnServer struct {
33+
udpListener net.PacketConn
34+
turnServer *turn.Server
35+
AuthHandler func(username string, realm string, srcAddr net.Addr) ([]byte, bool)
36+
}
37+
38+
func NewTurnServer(config TurnServerConfig) *TurnServer {
39+
server := &TurnServer{
40+
AuthHandler: nil,
41+
}
42+
if len(config.PublicIP) == 0 {
43+
logger.Panicf("'public-ip' is required")
44+
}
45+
udpListener, err := net.ListenPacket("udp4", "0.0.0.0:"+strconv.Itoa(config.Port))
46+
if err != nil {
47+
logger.Panicf("Failed to create TURN server listener: %s", err)
48+
}
49+
server.udpListener = udpListener
50+
51+
turnServer, err := turn.NewServer(turn.ServerConfig{
52+
Realm: config.Realm,
53+
AuthHandler: server.HandleAuthenticate,
54+
PacketConnConfigs: []turn.PacketConnConfig{
55+
{
56+
PacketConn: udpListener,
57+
RelayAddressGenerator: &turn.RelayAddressGeneratorStatic{
58+
RelayAddress: net.ParseIP(config.PublicIP),
59+
Address: "0.0.0.0",
60+
},
61+
},
62+
},
63+
})
64+
if err != nil {
65+
logger.Panicf("%v", err)
66+
}
67+
server.turnServer = turnServer
68+
return server
69+
}
70+
71+
func (s *TurnServer) HandleAuthenticate(username string, realm string, srcAddr net.Addr) ([]byte, bool) {
72+
if s.AuthHandler != nil {
73+
return s.AuthHandler(username, realm, srcAddr)
74+
}
75+
return nil, false
76+
}
77+
78+
func (s *TurnServer) Close() error {
79+
return s.turnServer.Close()
80+
}

pkg/websocket/server.go

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,38 @@ import (
1010
)
1111

1212
type WebSocketServerConfig struct {
13-
Host string
14-
Port int
15-
CertFile string
16-
KeyFile string
17-
HTMLRoot string
18-
WebSocketPath string
13+
Host string
14+
Port int
15+
CertFile string
16+
KeyFile string
17+
HTMLRoot string
18+
WebSocketPath string
19+
TurnServerPath string
1920
}
2021

2122
func DefaultConfig() WebSocketServerConfig {
2223
return WebSocketServerConfig{
23-
Host: "0.0.0.0",
24-
Port: 8086,
25-
HTMLRoot: "html",
26-
WebSocketPath: "/ws",
24+
Host: "0.0.0.0",
25+
Port: 8086,
26+
HTMLRoot: "html",
27+
WebSocketPath: "/ws",
28+
TurnServerPath: "/turnServer",
2729
}
2830
}
2931

3032
type WebSocketServer struct {
31-
handleWebSocket func(ws *transport.WebSocketTransport, request *http.Request)
33+
handleWebSocket func(ws *transport.WebSocketTransport, request *http.Request)
34+
handleTurnServer func(writer http.ResponseWriter, request *http.Request)
3235
// Websocket upgrader
3336
upgrader websocket.Upgrader
3437
}
3538

36-
func NewWebSocketServer(handler func(ws *transport.WebSocketTransport, request *http.Request)) *WebSocketServer {
39+
func NewWebSocketServer(
40+
wsHandler func(ws *transport.WebSocketTransport, request *http.Request),
41+
turnServerHandler func(writer http.ResponseWriter, request *http.Request)) *WebSocketServer {
3742
var server = &WebSocketServer{
38-
handleWebSocket: handler,
43+
handleWebSocket: wsHandler,
44+
handleTurnServer: turnServerHandler,
3945
}
4046
server.upgrader = websocket.Upgrader{
4147
CheckOrigin: func(r *http.Request) bool {
@@ -57,10 +63,15 @@ func (server *WebSocketServer) handleWebSocketRequest(writer http.ResponseWriter
5763
wsTransport.ReadMessage()
5864
}
5965

66+
func (server *WebSocketServer) handleTurnServerRequest(writer http.ResponseWriter, request *http.Request) {
67+
server.handleTurnServer(writer, request)
68+
}
69+
6070
// Bind .
6171
func (server *WebSocketServer) Bind(cfg WebSocketServerConfig) {
6272
// Websocket handle func
6373
http.HandleFunc(cfg.WebSocketPath, server.handleWebSocketRequest)
74+
http.HandleFunc(cfg.TurnServerPath, server.handleTurnServerRequest)
6475
http.Handle("/", http.FileServer(http.Dir(cfg.HTMLRoot)))
6576
logger.Infof("WebSocketServer listening on: %s:%d", cfg.Host, cfg.Port)
6677
// http.ListenAndServe(cfg.Host+":"+strconv.Itoa(cfg.Port), nil)

0 commit comments

Comments
 (0)