Поддержка динамического запроса TURN (ICE) серверов для связи.

This commit is contained in:
set
2026-03-17 15:27:14 +02:00
parent c8141f00bc
commit 96df1e52f9
5 changed files with 54 additions and 0 deletions

View File

@@ -48,6 +48,11 @@ func Bootstrap() {
logger.LogInfoMessage("starting without TURN server, peer connections may fail if clients are behind symmetric NATs") logger.LogInfoMessage("starting without TURN server, peer connections may fail if clients are behind symmetric NATs")
} else { } else {
logger.LogInfoMessage("server TURN started at 0.0.0.0:3478") 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() defer turnServer.Close()
} }
} else { } else {

View File

@@ -15,4 +15,6 @@ var (
SDP_ANSWER_RENEGOTIATION = 0x07 SDP_ANSWER_RENEGOTIATION = 0x07
// Check life для проверки соединения с сервером SFU // Check life для проверки соединения с сервером SFU
CHECK_LIFE = 0xAE CHECK_LIFE = 0xAE
// Запрос от бекенда на получение данных для подключения к TURN серверу
TURN_ASK = 0x19
) )

View File

@@ -20,4 +20,6 @@ var (
SDP_ANSWER = 0x05 SDP_ANSWER = 0x05
// Сервер SFU отправит этот пакет бекенду при получении Check life для подтверждения, что соединение живо // Сервер SFU отправит этот пакет бекенду при получении Check life для подтверждения, что соединение живо
CHECK_LIFE_SUCCESS = 0xAE CHECK_LIFE_SUCCESS = 0xAE
// Ответ от сервера при вопросе о TURN
TURN_SERVER = 0x19
) )

View File

@@ -7,6 +7,7 @@ import (
"g365sfu/network" "g365sfu/network"
"g365sfu/sfu" "g365sfu/sfu"
connection "g365sfu/socket/struct" connection "g365sfu/socket/struct"
"g365sfu/turn"
"g365sfu/utils" "g365sfu/utils"
"net/http" "net/http"
"os" "os"
@@ -218,5 +219,41 @@ func processData(data <-chan []byte, connection *connection.Connection) {
connection.WriteBinary(response.Bytes()) connection.WriteBinary(response.Bytes())
continue continue
} }
// Запрос от бекенда на получение данных для подключения к TURN серверу
if packetId == byte(network.TURN_ASK) && turn.TURN_PUBLIC_IP != "" {
// Отвечаем только в том случае, если TURN сервер был успешно запущен и данные для подключения к нему были заполнены
// Отправляем два пакета один на tcp сервер другой на udp сервер, так как некоторые клиенты могут поддерживать только один из этих протоколов
//tcp
response := bytebuffer.Allocate(1 + 4 + len([]byte(turn.TURN_PUBLIC_IP)) + 4 + len([]byte(turn.TURN_USER)) + 4 + len([]byte(turn.TURN_PASS)) + 4 + len([]byte("tcp")))
response.Put(byte(network.TURN_SERVER))
response.PutUint32(uint32(len([]byte(turn.TURN_PUBLIC_IP))))
response.PutBytes([]byte(turn.TURN_PUBLIC_IP))
response.PutUint32(uint32(len([]byte(turn.TURN_USER))))
response.PutBytes([]byte(turn.TURN_USER))
response.PutUint32(uint32(len([]byte(turn.TURN_PASS))))
response.PutBytes([]byte(turn.TURN_PASS))
response.PutUint32(uint32(len([]byte("tcp"))))
response.PutBytes([]byte("tcp"))
response.Flip()
connection.WriteBinary(response.Bytes())
//udp
responseUDP := bytebuffer.Allocate(1 + 4 + len([]byte(turn.TURN_PUBLIC_IP)) + 4 + len([]byte(turn.TURN_USER)) + 4 + len([]byte(turn.TURN_PASS)) + 4 + len([]byte("udp")))
responseUDP.Put(byte(network.TURN_SERVER))
responseUDP.PutUint32(uint32(len([]byte(turn.TURN_PUBLIC_IP))))
responseUDP.PutBytes([]byte(turn.TURN_PUBLIC_IP))
responseUDP.PutUint32(uint32(len([]byte(turn.TURN_USER))))
responseUDP.PutBytes([]byte(turn.TURN_USER))
responseUDP.PutUint32(uint32(len([]byte(turn.TURN_PASS))))
responseUDP.PutBytes([]byte(turn.TURN_PASS))
responseUDP.PutUint32(uint32(len([]byte("udp"))))
responseUDP.PutBytes([]byte("udp"))
responseUDP.Flip()
connection.WriteBinary(responseUDP.Bytes())
continue
}
} }
} }

8
turn/provider.go Normal file
View File

@@ -0,0 +1,8 @@
package turn
// Заполнится если сервер запустится успешно
var (
TURN_PUBLIC_IP = ""
TURN_USER = ""
TURN_PASS = ""
)