Hi all. I have the following code using Gorilla implementing a WebSocket server, this websocket will check user messages i the database and if it finds unread messages, it’ll deliver those messages to that user. All should happen inside msgTicker.C, the problem is that when I close the client page, it still executes the ticker a couple times before stops. How can I know IMMEDIATELY when the client has been disconnected or closed the page? Below my code;
package main
import (
"log"
"net/http"
"time"
"github.com/gorilla/websocket"
const (
// Time allowed to write the file to the client.
writeWait = 10 * time.Second
// Time allowed to read the next pong message from the client.
pongWait = 60 * time.Second
// Send pings to client with this period. Must be less than pongWait.
pingPeriod = (pongWait * 9) / 10
// Poll file for changes with this period.
msgPeriod = 10 * time.Second
var (
upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true
func reader(ws *websocket.Conn) {
defer ws.Close()
ws.SetReadLimit(512)
ws.SetReadDeadline(time.Now().Add(pongWait))
ws.SetPongHandler(func(string) error { ws.SetReadDeadline(time.Now().Add(pongWait)); return nil })
for {
_, _, err := ws.ReadMessage()
if err != nil {
break
func writer(ws *websocket.Conn, idUsuario string) {
pingTicker := time.NewTicker(pingPeriod)
msgTicker := time.NewTicker(msgPeriod)
defer func() {
pingTicker.Stop()
msgTicker.Stop()
ws.Close()
for {
select {
case <-msgTicker.C:
var p []byte
//var err error
//VERIFICAR AS MENSAGENS DO USUÁRIO AQUI NO BANCO PELO idUsuario.
//NA VARIÁVEL "p" VAI O PACOTE PARA O CLIENTE.
p = nil //só para teste, tirar depois.
//p = []byte("TESTE CONEXÃO WEBSOCKET!! IDUSUARIO: " + idUsuario)
println("TESTE CONEXÃO.")
if p != nil {
ws.SetWriteDeadline(time.Now().Add(writeWait))
if err := ws.WriteMessage(websocket.TextMessage, p); err == nil {
//pacote enviado, dar update no banco aqui e setar as mensagens como recebido = 1
} else {
return
case <-pingTicker.C:
ws.SetWriteDeadline(time.Now().Add(writeWait))
if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
return
func wswebverificamensagensusuario(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
if _, ok := err.(websocket.HandshakeError); !ok {
log.Println(err)
println(err.Error())
return
go writer(ws, r.FormValue("idusuario"))
reader(ws)
In Conn struct (ws) you have methods like PingHandler, PongHandler, CloseHandler, you can probably use them to do connection check.
godoc.org