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/websocketA 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 Também na biblioteca
Monitoramento de aplicações TypeScript: ferramentas e bibliotecas
Trabalho com imagens em PHP: visão geral de bibliotecas e ferramentas