Files
g365sfu/socket/socket.go

90 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package socket
import (
"g365sfu/logger"
"g365sfu/utils"
"net/http"
"os"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
// Разрешаем со всех origin
return true
},
}
// Получение секретного ключа из переменных окружения
func getSecret() string {
return os.Getenv("SECRET")
}
// Обработчик WebSocket соединений
func HandleWebSocket(w http.ResponseWriter, r *http.Request) {
conn, _ := upgrader.Upgrade(w, r, nil)
defer conn.Close()
// Канал для передачи байтов
dataChan := make(chan []byte)
var connection = &Connection{
Identificator: randomSocketIdentifier(),
Socket: conn,
}
AddSocket(connection)
// Удаление сокета из хранилища при закрытии соединения
defer RemoveSocket(connection.Identificator)
// Запуск обработчика в горутине
go processData(dataChan, connection)
for {
messageType, p, err := conn.ReadMessage()
if err != nil || messageType != websocket.BinaryMessage {
break
}
// Передача байтов для обработки
dataChan <- p
}
}
// Генерация случайного идентификатора для сокета
func randomSocketIdentifier() string {
// Генерация случайного идентификатора для сокета
return "sock_" + utils.RandomString(10)
}
func processData(data <-chan []byte, connection *Connection) {
for bytes := range data {
// Логика обработки байтов
if bytes[0] == 0x01 {
// Это рукопожатие, дальше сравниваем секретные ключи
// Секретный ключ идет сразу после первого байта и до конца сообщения
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")
connection.Socket.Close()
return
}
// Так как следующие пакеты требуют обязательного завершения рукопожатия, нужно проверять, что сокет уже прошел рукопожатие
if _, exists := GetSocket(connection.Identificator); !exists {
logger.LogWarnMessage("received data from " + connection.Socket.RemoteAddr().String() + " but it has not completed handshake")
connection.Socket.Close()
return
}
// Следующие типы сообщений
}
}