Moxitech-Websocket-Do/server/App/internal/fiber/fiber.go
2024-09-01 19:43:58 +07:00

221 lines
6.1 KiB
Go
Raw Permalink 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 fiber
import (
"fmt"
"os"
"time"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/websocket/v2"
)
// Структуры для данных
type User struct {
Username string `json:"username"`
Secret []string `json:"secret_words"`
}
type Group struct {
Name string `json:"name"`
Users []string `json:"users"`
Messages []Message `json:"messages"`
}
type Message struct {
Title string `json:"title"`
Type string `json:"type"`
Additionally struct {
Timestamp int64 `json:"ts"`
Payload string `json:"payload"`
} `json:"additionally"`
}
var (
users = make(map[string]User) // карта пользователей по никнейму
groups = make(map[string]Group) // карта групп по имени
)
func getAllGroups(c *fiber.Ctx) error {
// groupList := []GroupData{}
// for _, group := range groups {
// groupList = append(groupList, group)
// }
return c.JSON(groups)
}
// Функция генерации уникального набора слов (можно заменить на более сложную логику)
func generateSecretWords() []string {
return []string{"word1", "word2", "word3", "word4", "word5", "word6", "word7", "word8"}
}
// Обработчик регистрации
func register(c *fiber.Ctx) error {
username := c.Query("username")
if username == "" {
return c.Status(400).JSON(fiber.Map{"error": "Username is required"})
}
if _, exists := users[username]; exists {
return c.Status(400).JSON(fiber.Map{"error": "Username already exists"})
}
secretWords := generateSecretWords()
users[username] = User{
Username: username,
Secret: secretWords,
}
return c.JSON(fiber.Map{
"username": username,
"secret_words": secretWords,
})
}
// Обработчик создания группы
func createGroup(c *fiber.Ctx) error {
groupName := c.Query("group_name")
username := c.Query("username")
if groupName == "" || username == "" {
return c.Status(400).JSON(fiber.Map{"error": "Group name and username are required"})
}
if _, exists := groups[groupName]; exists {
return c.Status(400).JSON(fiber.Map{"error": "Group already exists"})
}
if _, exists := users[username]; !exists {
return c.Status(400).JSON(fiber.Map{"error": "User does not exist"})
}
group := Group{
Name: groupName,
Users: []string{username},
Messages: []Message{},
}
groups[groupName] = group
return c.JSON(group)
}
// Обработчик добавления пользователя в группу
func addUserToGroup(c *fiber.Ctx) error {
groupName := c.Query("group_name")
username := c.Query("username")
if groupName == "" || username == "" {
return c.Status(400).JSON(fiber.Map{"error": "Group name and username are required"})
}
group, exists := groups[groupName]
if !exists {
return c.Status(400).JSON(fiber.Map{"error": "Group does not exist"})
}
if _, exists := users[username]; !exists {
return c.Status(400).JSON(fiber.Map{"error": "User does not exist"})
}
group.Users = append(group.Users, username)
groups[groupName] = group
return c.JSON(group)
}
// Обработчик подключения через WebSocket для синхронизации заметок
func syncGroup(c *fiber.Ctx) error {
groupName := c.Params("grouphash")
if websocket.IsWebSocketUpgrade(c) {
c.Locals("groupName", groupName)
return c.Next()
}
return c.Status(426).SendString("Upgrade required")
}
func handleWebSocket(c *websocket.Conn) {
groupName := c.Locals("groupName").(string)
for {
// Пример синхронизации: получение сообщения и его обработка
msgType, msg, err := c.ReadMessage()
if err != nil {
break
}
// Обновляем данные группы (на практике нужно добавить больше логики)
group := groups[groupName]
group.Messages = append(group.Messages, Message{
Title: string(msg),
Type: "text",
Additionally: struct {
Timestamp int64 `json:"ts"`
Payload string `json:"payload"`
}{
Timestamp: time.Now().Unix(),
Payload: string(msg),
},
})
groups[groupName] = group
// Отправка обновленных данных всем пользователям группы
for _, user := range group.Users {
fmt.Printf("Sending update to user: %s\n", user)
err = c.WriteMessage(msgType, []byte("New message in group: "+groupName))
if err != nil {
break
}
}
}
}
func addMessageToGroup(c *fiber.Ctx) error {
groupName := c.Params("grouphash")
group, exists := groups[groupName]
if !exists {
return c.Status(404).JSON(fiber.Map{"error": "Group not found"})
}
var newMessage Message
if err := c.BodyParser(&newMessage); err != nil {
return c.Status(400).JSON(fiber.Map{"error": "Invalid request payload"})
}
// Добавление метаданных
newMessage.Additionally.Timestamp = time.Now().Unix()
group.Messages = append(group.Messages, newMessage)
groups[groupName] = group
return c.JSON(group)
}
// Основная функция запуска сервера
func SpawnFiberCtx() error {
app := fiber.New()
app.Use(cors.New(cors.Config{
AllowOrigins: "*",
AllowMethods: "*",
AllowHeaders: "*",
}))
// app.Use()
app.Get("/", func(c *fiber.Ctx) error {
return c.SendStatus(404)
})
// Регистрация пользователя
app.Get("/register", register)
// Создание группы
app.Get("/create_group", createGroup)
// Добавление пользователя в группу
app.Get("/add_user_to_group", addUserToGroup)
// Обработчик добавления нового сообщения в группу
app.Post("/grouphash::grouphash/addMessage", addMessageToGroup)
// Возвращает все группы
app.Get("/getAllGroups", getAllGroups)
// Подключение к группе через WebSocket
app.Get("/connect/grouphash::grouphash", syncGroup)
// Обработчик для работы с WebSocket
app.Use("/ws", websocket.New(handleWebSocket))
return app.Listen("0.0.0.0:" + os.Getenv("API_PORT"))
}