gofiber / fiber

āš”ļø Express inspired web framework written in Go
https://gofiber.io
MIT License
33.92k stars 1.67k forks source link

šŸ¤— [Question]: Lost MAP data #3195

Closed RhaPT closed 1 day ago

RhaPT commented 2 days ago

Question Description

Sorry about my English. I created a page with javascript where it creates a websocket and receives a unique id ("Sec-Websocket-Key") for that instance, then it uses this id whenever it makes a request to the api (sends in the header an X-Id with this value), the api stores data within a map indexed by X-Id

If you open another window in the same browser (if use other browser no problem) and call the same page, it will create a new instance for in websocket and at that time it automatically changes the MAP.

Example the first time you open the page: map[] after adding a value : map[GlYkSNQ6GQMFtdkHGqlxZw==:GlYkSNQ6GQMFtdkHGqlxZw==] after open new window in same browser: map[keep-aliveMFtdkHGqlxZw==:keep-aliveMFtdkHGqlxZw==]

Does anyone know why the Map changes?

Code Snippet (optional)

package main

import (
    "log"
    "github.com/gofiber/contrib/websocket"
    "github.com/gofiber/fiber/v2"
)

var Xpto map[string]string

func init() {
    Xpto = make(map[string]string)
}

func main() {
    app := fiber.New()

    app.Static("/", ".")

    api := app.Group("/api")
    api.Post("/add", setXpto)

    app.Use("/ws", func(c *fiber.Ctx) error {
        if websocket.IsWebSocketUpgrade(c) {
            return c.Next()
        }
        return fiber.ErrUpgradeRequired
    })
    app.Get("/ws", websocket.New(func(c *websocket.Conn) {
        var (
            mt  int
            msg []byte
            err error
        )
        for {
            if mt, msg, err = c.ReadMessage(); err != nil {
                log.Println("read:", err)
                break
            }
            if string(msg) == "1" {
                newID := c.Headers("Sec-Websocket-Key", "")
                c.WriteMessage(mt, []byte(newID))
            }
            log.Println(Xpto)
        }
    }))
    log.Fatal(app.Listen(":3000"))

    log.Panicln(Xpto)
}

func setXpto(c *fiber.Ctx) error {
    xID := c.Get("X-Id", "")
    Xpto[xID] = xID
    log.Println(Xpto)
    c.Status(fiber.StatusOK)
    return c.JSON(Xpto)
}

Checklist:

welcome[bot] commented 2 days ago

Thanks for opening your first issue here! šŸŽ‰ Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

gaby commented 1 day ago

@RhaPT First you never call init(). Second, the values from the context are only valid during the handler execution.

Here:

func setXpto(c *fiber.Ctx) error {
    xID := c.Get("X-Id", "")
    Xpto[xID] = xID
    log.Println(Xpto)
    c.Status(fiber.StatusOK)
    return c.JSON(Xpto)
}

You have to copy the value form the context like this:

xID := utils.CopyString(c.Get("X-Id", ""))

Documentation is here: https://docs.gofiber.io/#zero-allocation

gaby commented 1 day ago

@RhaPT Did that fix your issue?

RhaPT commented 1 day ago

Thanks for your help

gaby commented 1 day ago

Awesome šŸ’Ŗ