WebSocket em Go: biblioteca gorilla/websocket e implementação padrão

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Biblioteca WebSocket Go (Golang): gorilla/websocket e o padrão net/http



WebSocket é um protocolo que fornece comunicação full-duplex entre cliente e servidor através de uma única conexão TCP de longa duração. Ao contrário do HTTP clássico, após o estabelecimento da conexão, os dados podem ser transmitidos em ambas as direções a qualquer momento, sem solicitações constantes do cliente. Esta é a solução ideal para chats, notificações em tempo real, jogos online e plataformas de negociação.



No ecossistema Go (Golang), existem várias maneiras de trabalhar com WebSocket. A biblioteca mais popular e testada pelo tempo é a gorilla/websocket. No entanto, a partir do Go 1.22, tornou-se possível implementar um servidor WebSocket básico sem dependências de terceiros, usando o pacote padrão net/http. Neste artigo, abordaremos detalhadamente ambas as abordagens.



Instalação da biblioteca gorilla/websocket



Para começar a trabalhar com gorilla/websocket, instale-a via go get:



go get github.com/gorilla/websocket


A biblioteca fornece uma API conveniente para criar tanto a parte do servidor quanto a do cliente. Ela lida com o handshake, o enquadramento de mensagens, suporta compressão e ping/pong automáticos.



Servidor WebSocket com gorilla/websocket



Vamos considerar um exemplo de um servidor echo simples. O cliente envia uma mensagem e o servidor a retorna:



package main

import ( "log" "net/http" "github.com/gorilla/websocket")

var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true // permite qualquer origem (para desenvolvimento) },}

func echoHandler(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Print("Falha no upgrade:", err) return } defer conn.Close()

for { messageType, message, err := conn.ReadMessage() if err != nil { log.Println("Erro de leitura:", err) break } log.Printf("Recebido: %s", message)

if err := conn.WriteMessage(messageType, message); err != nil { log.Println("Erro de escrita:", err) break } }}

func main() { http.HandleFunc("/echo", echoHandler) log.Fatal(http.ListenAndServe(":8080", nil))}


Aqui, Upgrader converte uma solicitação HTTP comum em uma conexão WebSocket. A função CheckOrigin controla de quais domínios as conexões são permitidas. Em produção, é recomendável verificar origens específicas.



Cliente WebSocket com gorilla/websocket



Exemplo de um cliente que se conecta ao nosso servidor e envia uma mensagem:



package main

import ( "log" "os" "os/signal" "time" "github.com/gorilla/websocket")

func main() { interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt)

url := "ws://localhost:8080/echo" c, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { log.Fatal("dial:", err) } defer c.Close()

done := make(chan struct{})

// Goroutine para ler as respostas go func() { defer close(done) for { _, message, err := c.ReadMessage() if err != nil { log.Println("read:", err) return } log.Printf("recv: %s", message) } }()

// Envio de mensagem ticker := time.NewTicker(time.Second) defer ticker.Stop()

for { select { case <-done: return case t := <-ticker.C: err := c.WriteMessage(websocket.TextMessage, []byte(t.String())) if err != nil { log.Println("write:", err) return } case <-interrupt: log

Recommendations