#Issues using websockets to refresh file server

23 messages · Page 1 of 1 (latest)

surreal meadow
#

Once you've upgraded/hijacked a websocket connection I don't believe you should close it until you're done using it.

The defer ws.Close() you've got in the wsHandler is doing that, but you're continuing to use the websocket connection inside your goroutine.

I believe what you're going to want to do instead is something like calling ws.ReadMessage() in a loop inside and only call ws.Close() once you're done with that particular websocket connection.

#

You are using the websocket connection like it's a one-time thing, but it's meant to be a long-lived, two-way connection.

celest shoal
#

call defer ws.Close() inside the goroutine (above the top for loop), and remove the bottom loop

#

you shouldnt need a goroutine at all, however

#
func wsHandler(w http.ResponseWriter, r *http.Request) {
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
        return
    }
    defer ws.Close()
         for {
            event := wsEvent{}

            select {
            case <-ReloadSignal:
                event.Type = "reload"
            case <-FinalQuitSignal:
                event.Type = "server_shutdown"
            }

            err = ws.WriteJSON(event)
            if err != nil {
                log.Println(err)
            }
        }
}
#

This should do it

surreal meadow
#

Yeah, let the http package spawn goroutines for you.

celest shoal
#

The issue here is that the goroutine runs off, but your http handler returns and closes the websocket

#

it shouldn't work at all, in the current state of affairs

#

do you refresh the web page or replace the content

#

the javascript running in the web page holds the websocket connection. When it's refreshed, it drops the collection then it's gcd by the browser

#

(your handler was wrong nonetheless)

#

but this time, your go code should be right

celest shoal
#

when the page closes, your http Request context should get closed

#

listen to that close to know when to close your go websocket

#

Your frontend is dropping the connection anyways, so you have to close it when it's refreshed on the backend

#
func wsHandler(w http.ResponseWriter, r *http.Request) {
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
        return
    }
    defer ws.Close()
     for {
            event := wsEvent{}

            select {
            case <-ReloadSignal:
                event.Type = "reload"
            case <-FinalQuitSignal:
                event.Type = "server_shutdown"
            case <-r.Context().Done():
                return
            }

            err = ws.WriteJSON(event)
            if err != nil {
                log.Println(err)
            }
        }
}
#

Something along those lines

#

here you're waiting for frontend to close and closing your handler

celest shoal
#

Well it's not inappropriate, you're telling the webpage it should refresh

#

so the webpage refreshes

#

and your connection gets dropped

#

here, you close right after sending the message, which is just fine