Einführung in WebSocket in Go: Warum Echtzeit?
Moderne Webanwendungen erfordern zunehmend eine sofortige Datenzustellung. Das traditionelle HTTP-Anfrage/Antwort-Modell ist mit Aufgaben wie Chats, Online-Spielen, Börsenkursen und Monitoring-Dashboards nicht mehr ausreichend. Hier kommt WebSocket ins Spiel – ein Protokoll, das eine permanente bidirektionale Verbindung zwischen Client und Server ermöglicht. In diesem Artikel werden wir uns damit befassen, wie man Echtzeitanwendungen in Go (Golang) mit WebSocket erstellt, von der Installation bis hin zu Produktionslösungen.
Go ist aufgrund seines leichten Nebenläufigkeitsmodells (Goroutinen) und seiner hohen Leistung ideal für WebSocket geeignet. Wir werden den Weg von einem einfachen Echo-Server bis hin zu einem vollwertigen Chat und einem Monitoringsystem gehen.
Grundlagen von WebSocket und Einrichtung der Umgebung
Was ist WebSocket?
WebSocket ist ein Protokoll, das über TCP arbeitet. Es beginnt mit einem HTTP-Handshake (Upgrade), woraufhin die Verbindung auf einen permanenten bidirektionalen Kanal umschaltet. Im Gegensatz zu HTTP kann der Server Daten ohne Anfrage an den Client senden – das ist die Grundlage für Echtzeit.
Installation und Bibliotheken
In Go gibt es keine Standardbibliothek für WebSocket, aber es gibt die beliebte Bibliothek gorilla/websocket. Installieren wir sie:
go get github.com/gorilla/websocketMan kann auch nhooyr.io/websocket (eine modernere Alternative) verwenden, aber in diesem Artikel konzentrieren wir uns auf gorilla, da es am weitesten verbreitet ist.
Erster WebSocket-Server in Go
Schreiben wir einen einfachen Echo-Server, der eine Nachricht empfängt und zurücksendet:
package main
import ( "log" "net/http" "github.com/gorilla/websocket")
var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true // für die Entwicklung },}
func echoHandler(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Print("Upgrade:", err) return } defer conn.Close()
for { mt, message, err := conn.ReadMessage() if err != nil { log.Println("Read:", err) break } log.Printf("Received: %s", message) err = conn.WriteMessage(mt, message) if err != nil { log.Println("Write:", err) break } }}
func main() { http.HandleFunc("/echo", echoHandler) log.Println("Server started on :8080") log.Fatal(http.ListenAndServe(":8080", nil))}Dies ist ein minimales funktionierendes Beispiel. Beachten Sie den Upgrader – er überprüft die HTTP-Header und schaltet die Verbindung um.
Architektur einer Echtzeitanwendung: Chat in Go
Verwaltung von Verbindungen
Für einen Chat müssen mehrere Clients verwaltet werden. Erstellen wir eine Struktur Hub, die alle aktiven Verbindungen speichert und Nachrichten verteilt:
type Client struct { hub *Hub conn *websocket.Conn send chan []byte}
type Hub struct { clients map[*Client]bool broadcast chan []byte register chan *Client unregister chan *Client}
func newHub() *Hub { return &Hub{ clients: make(map[*Client]bool), broadcast: make(chan []byte), register: make(chan *Client), unregister: make(chan *Client), }}
func (h *Hub) run() { for { select { case client := <-h.register: h.clients[client] = true case client := <-h.unregister: if _, ok := h.clients[client]; ok { delete(h.clients, client) close(client.send) } case message := <-h.broadcast: for client := range h.clients { select { case client.send <- message: default: