Готовая реализация handshake
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
// Следующие типы сообщений
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user