添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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