Готовая реализация handshake

This commit is contained in:
set
2026-03-10 15:49:29 +02:00
parent 1f706385f8
commit c9aade2be3
4 changed files with 65 additions and 4 deletions

View File

@@ -1,8 +1,10 @@
package socket
import (
"fmt"
"g365sfu/logger"
"math/rand"
"net/http"
"os"
"github.com/gorilla/websocket"
)
@@ -16,6 +18,10 @@ var upgrader = websocket.Upgrader{
},
}
func getSecret() string {
return os.Getenv("SECRET")
}
// Обработчик WebSocket соединений
func HandleWebSocket(w http.ResponseWriter, r *http.Request) {
conn, _ := upgrader.Upgrade(w, r, nil)
@@ -24,8 +30,16 @@ func HandleWebSocket(w http.ResponseWriter, r *http.Request) {
// Канал для передачи байтов
dataChan := make(chan []byte)
var connection = &Connection{
Identificator: randomSocketIdentifier(),
Socket: conn,
}
AddSocket(connection)
// Удаление сокета из хранилища при закрытии соединения
defer RemoveSocket(connection.Identificator)
// Запуск обработчика в горутине
go processData(dataChan)
go processData(dataChan, connection)
for {
messageType, p, err := conn.ReadMessage()
@@ -37,11 +51,46 @@ func HandleWebSocket(w http.ResponseWriter, r *http.Request) {
}
}
func processData(data <-chan []byte) {
// Генерация случайного идентификатора для сокета
func randomSocketIdentifier() string {
// Генерация случайного идентификатора для сокета
return "sock_" + randomString(10)
}
// Генерация случайной строки заданной длины
func randomString(n int) string {
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
b := make([]byte, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
func processData(data <-chan []byte, connection *Connection) {
for bytes := range data {
// Логика обработки байтов
if bytes[0] == 0x01 {
fmt.Print("Type 0x01 received")
// Это рукопожатие, дальше сравниваем секретные ключи
// Секретный ключ идет сразу после первого байта и до конца сообщения
receivedSecret := string(bytes[1:])
if receivedSecret == getSecret() {
logger.LogSuccessMessage("success handshake from " + connection.Socket.RemoteAddr().String())
AddSocket(connection)
connection.Socket.WriteMessage(websocket.BinaryMessage, []byte{0x01})
return
}
connection.Socket.WriteMessage(websocket.BinaryMessage, []byte{0xFF})
logger.LogWarnMessage("failed handshake from " + connection.Socket.RemoteAddr().String() + " because of invalid secret key")
return
}
// Так как следующие пакеты требуют обязательного завершения рукопожатия, нужно проверять, что сокет уже прошел рукопожатие
if _, exists := GetSocket(connection.Identificator); !exists {
logger.LogWarnMessage("received data from " + connection.Socket.RemoteAddr().String() + " but it has not completed handshake")
return
}
// Следующие типы сообщений
}
}