129 lines
4.8 KiB
Go
129 lines
4.8 KiB
Go
package boot
|
|
|
|
import (
|
|
"encoding/json"
|
|
"g365sfu/bytebuffer"
|
|
"g365sfu/logger"
|
|
"g365sfu/network"
|
|
"g365sfu/sfu"
|
|
"g365sfu/socket"
|
|
connection "g365sfu/socket/struct"
|
|
"g365sfu/turn"
|
|
"g365sfu/utils"
|
|
"net/http"
|
|
"os"
|
|
|
|
"github.com/joho/godotenv"
|
|
"github.com/pion/webrtc/v4"
|
|
)
|
|
|
|
func Bootstrap() {
|
|
godotenv.Load()
|
|
sfu.InitWebRTCEngines()
|
|
if os.Getenv("SECRET") == "" {
|
|
logger.LogErrorMessage("server failed to start because not set secret key in .env variables")
|
|
return
|
|
}
|
|
http.HandleFunc("/", socket.HandleWebSocket)
|
|
port := os.Getenv("PORT")
|
|
if port == "" {
|
|
port = "1001"
|
|
}
|
|
sfu.OnLocalICECandidate = OnLocalICECandidate
|
|
sfu.OnServerOffer = OnServerOffer
|
|
sfu.OnRoomDelete = OnRoomDelete
|
|
sfu.OnPeerDisconnected = OnPeerDisconnected
|
|
if os.Getenv("TURN_ALLOW") == "true" {
|
|
turnServer, err := turn.Start(turn.Config{
|
|
ListenAddr: "0.0.0.0:3478",
|
|
PublicIP: os.Getenv("TURN_PUBLIC_IP"),
|
|
Realm: "g365sfu",
|
|
Username: os.Getenv("TURN_USER"),
|
|
Password: os.Getenv("TURN_PASS"),
|
|
MinRelayPort: uint16(utils.AtoiOrDefault(os.Getenv("TURN_PORT_RANGE_FROM"), 40000)),
|
|
MaxRelayPort: uint16(utils.AtoiOrDefault(os.Getenv("TURN_PORT_RANGE_TO"), 50000)),
|
|
})
|
|
if err != nil {
|
|
logger.LogWarnMessage("error while starting TURN server: " + err.Error())
|
|
logger.LogInfoMessage("starting without TURN server, peer connections may fail if clients are behind symmetric NATs")
|
|
} else {
|
|
logger.LogInfoMessage("server TURN started at 0.0.0.0:3478")
|
|
// Заполняем глобальные переменные для TURN провайдера, чтобы их могли использовать другие части приложения
|
|
// Обратите внимание, заполняем их только в случе успешного старта Turn сервера
|
|
turn.TURN_PASS = os.Getenv("TURN_PASS")
|
|
turn.TURN_USER = os.Getenv("TURN_USER")
|
|
turn.TURN_PUBLIC_IP = os.Getenv("TURN_PUBLIC_IP")
|
|
defer turnServer.Close()
|
|
}
|
|
} else {
|
|
// TURN сервер выключен в конфиге, что может влиять на соединение некоторых пользователей
|
|
logger.LogInfoMessage("starting without TURN server, peer connections may fail if clients are behind symmetric NATs")
|
|
}
|
|
logger.LogInfoMessage("server started at x.x.x.x:" + port)
|
|
http.ListenAndServe(":"+port, nil)
|
|
}
|
|
|
|
// Коллбек для обработки новых ICE кандидатов от сервера к пиру
|
|
func OnLocalICECandidate(roomID string, peerID string, candidate webrtc.ICECandidateInit) {
|
|
room, exists := sfu.GetRoom(roomID)
|
|
if !exists {
|
|
logger.LogWarnMessage("tried to send local ICE candidate to non existing room " + roomID)
|
|
return
|
|
}
|
|
jsonCandidate, _ := json.Marshal(candidate)
|
|
buffer := bytebuffer.Allocate(
|
|
1 + 4 + len([]byte(roomID)) + 4 + len([]byte(peerID)) + 4 + len(jsonCandidate),
|
|
)
|
|
buffer.Put(byte(network.ON_LOCAL_ICE_CANDIDATE))
|
|
buffer.PutUint32(uint32(len([]byte(roomID))))
|
|
buffer.PutBytes([]byte(roomID))
|
|
buffer.PutUint32(uint32(len([]byte(peerID))))
|
|
buffer.PutBytes([]byte(peerID))
|
|
buffer.PutUint32(uint32(len([]byte(jsonCandidate))))
|
|
buffer.PutBytes([]byte(jsonCandidate))
|
|
buffer.Flip()
|
|
room.Server.WriteBinary(buffer.Bytes())
|
|
}
|
|
|
|
// Обработка нового оффера от сервера для конкретного пира (при renegotiation)
|
|
func OnServerOffer(roomID string, peerID string, offer webrtc.SessionDescription) {
|
|
room, exists := sfu.GetRoom(roomID)
|
|
if !exists {
|
|
logger.LogWarnMessage("tried to send server offer to non existing room " + roomID)
|
|
return
|
|
}
|
|
jsonOffer, _ := json.Marshal(offer)
|
|
buffer := bytebuffer.Allocate(
|
|
1 + 4 + len([]byte(roomID)) + 4 + len([]byte(peerID)) + 4 + len(jsonOffer),
|
|
)
|
|
buffer.Put(byte(network.ON_SERVER_OFFER))
|
|
buffer.PutUint32(uint32(len([]byte(roomID))))
|
|
buffer.PutBytes([]byte(roomID))
|
|
buffer.PutUint32(uint32(len([]byte(peerID))))
|
|
buffer.PutBytes([]byte(peerID))
|
|
buffer.PutUint32(uint32(len([]byte(jsonOffer))))
|
|
buffer.PutBytes([]byte(jsonOffer))
|
|
buffer.Flip()
|
|
room.Server.WriteBinary(buffer.Bytes())
|
|
}
|
|
|
|
func OnRoomDelete(roomID string, server *connection.Connection) {
|
|
buffer := bytebuffer.Allocate(1 + 4 + len([]byte(roomID)))
|
|
buffer.Put(byte(network.ON_ROOM_DELETE))
|
|
buffer.PutUint32(uint32(len([]byte(roomID))))
|
|
buffer.PutBytes([]byte(roomID))
|
|
buffer.Flip()
|
|
server.WriteBinary(buffer.Bytes())
|
|
}
|
|
|
|
func OnPeerDisconnected(roomID string, peerID string, server *connection.Connection) {
|
|
buffer := bytebuffer.Allocate(1 + 4 + len([]byte(roomID)) + 4 + len([]byte(peerID)))
|
|
buffer.Put(byte(network.ON_PEER_DISCONNECTED))
|
|
buffer.PutUint32(uint32(len([]byte(roomID))))
|
|
buffer.PutBytes([]byte(roomID))
|
|
buffer.PutUint32(uint32(len([]byte(peerID))))
|
|
buffer.PutBytes([]byte(peerID))
|
|
buffer.Flip()
|
|
server.WriteBinary(buffer.Bytes())
|
|
}
|