Determining when Websocket is closed by client

7,687 views
Skip to first unread message

mge...@pivotallabs.com

unread,
Jul 1, 2013, 4:04:36 PM7/1/13
to golan...@googlegroups.com
Greetings all,

We are writing a websockets server that needs to detect when the client disconnects so we can stop running a loop.

Here is the code we have so far:


func myHandler(ws *websocket.Conn) {
    for {    // Until the client is disconnected! ... this is where I need help!
        // Do things while the client is connected...
    }
}

func main() {
    http.Handle("/tail", websocket.Handler(myHandler))
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        panic(err)
    }
}

While poking around the http docs we found the idea of a CloseNotifier but can not figure out how to get a hold of that for a websocket Connection like we have above.

Does anyone have any ideas?

Thanks in advance.

Jesse McNelis

unread,
Jul 2, 2013, 1:38:07 AM7/2/13
to mge...@pivotallabs.com, golang-nuts
On Tue, Jul 2, 2013 at 6:04 AM, <mge...@pivotallabs.com> wrote:
Greetings all,

We are writing a websockets server that needs to detect when the client disconnects so we can stop running a loop.

When you try to write to the client you'll get an error informing you that they have disconnected if they have disconnected.
This is how the CloseNotifier in net/http does it.

 
Here is the code we have so far:


func myHandler(ws *websocket.Conn) {
    for {    // Until the client is disconnected! ... this is where I need help!
        // Do things while the client is connected...
    }
}

func main() {
    http.Handle("/tail", websocket.Handler(myHandler))
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        panic(err)
    }
}

While poking around the http docs we found the idea of a CloseNotifier but can not figure out how to get a hold of that for a websocket Connection like we have above.

Does anyone have any ideas?

Thanks in advance.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
=====================
http://jessta.id.au

Chris Hines

unread,
Jul 2, 2013, 11:27:53 AM7/2/13
to golan...@googlegroups.com, mge...@pivotallabs.com
In my experience attempts to read from or write to the websocket will return an error if the client has disconnected. If your loop spends most of it's time blocking on websocket I/O then it should be pretty responsive to client disconnects. 

Sean Murphy

unread,
Jan 15, 2016, 12:46:08 AM1/15/16
to golang-nuts, mge...@pivotallabs.com
Thought I'd chime in:

reading detects the closed connection much quicker than writing. I decided to spin up a go-routine to do my writing, and then my reading was done on the server managed go-routine. I noticed that my read would stop much quicker, and the write would go on for quite awhile before it's err clause triggered. So I used a boolean available to both that if either one errored would break the read/write loops. This helped my server close out more nicely.

Example:

func WSServer(ws *websocket.Conn) {
        //TODO Set this connection up as a listener for system events
        isOpen := true

        //Start a go routine to listen
        go func() {
                for isOpen {
                        var data Message
                        err := websocket.JSON.Receive(ws, &data)
                        if err != nil {
                                isOpen = false
                                fmt.Println("Receiver Closing", err)
                                break
                        }
                        fmt.Println("Recieved", data.Msg, data.Count)
                }
        }()
        //Block this routine to send
        var count int
        for isOpen {
                time.Sleep(time.Second)
                err := websocket.JSON.Send(ws, Message{"Hello", count})
                if err != nil {
                        isOpen = false
                        fmt.Println("Sender Closing", err)
                        break
                }
                fmt.Println("Sent", count)
                count++
        }

        //TODO Cleanup
        //Remove the connection from all channels it is subscribed to
Reply all
Reply to author
Forward
0 new messages