slogan3

Houd me in de gaten bij het implementeren van WebSocket-communicatie in mijn Go-toepassing.

description

Door deze gids te volgen, verbeter je de interactiviteit en responsiviteit van je toepassing, waardoor realtime gegevensuitwisseling mogelijk wordt zonder voortdurend te hoeven polsen.

prompt

try_prompt

Help me bij het opzetten van WebSocket-communicatie in mijn Go-toepassing. Leg uit hoe je een WebSocket-server opzet, verbindingen beheert en berichte ... more
generate_helper
disclaimerOnPageApi image_legal_disclaimer...

ai_answers

provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een overzicht en voorbeeldcode voor het opzetten van een WebSocket-server in Go, inclusief het beheren van verbindingen en het verzenden/ontvangen van berichten voor een eenvoudige chattoepassing. ### 1. Vereisten Gebruik de populaire `gorilla/websocket` bibliotheek voor WebSocket-functionaliteit: ```bash go get github.com/gorilla/websocket ``` ### 2. WebSocket-server opzetten Hier is een basisstructuur voor een WebSocket-chatserver: ```go package main import ( "fmt" "log" "net/http" "sync" "github.com/gorilla/websocket" ) // Client vertegenwoordigt een verbonden client type Client struct { conn *websocket.Conn send chan []byte } // Hub beheert alle clients en broadcast type Hub struct { clients map[*Client]bool broadcast chan []byte register chan *Client unregister chan *Client mu sync.Mutex } var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, CheckOrigin: func(r *http.Request) bool { return true // Toevallig, in productie zou je dit beter beveiligen }, } 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.mu.Lock() h.clients[client] = true h.mu.Unlock() case client := <-h.unregister: h.mu.Lock() if _, ok := h.clients[client]; ok { delete(h.clients, client) close(client.send) } h.mu.Unlock() case message := <-h.broadcast: h.mu.Lock() for client := range h.clients { select { case client.send <- message: default: close(client.send) delete(h.clients, client) } } h.mu.Unlock() } } } func handleConnections(h *Hub, w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println("Upgrade fout:", err) return } client := &Client{conn: conn, send: make(chan []byte)} h.register <- client go client.writePump() client.readPump(h) } func (c *Client) readPump(h *Hub) { defer func() { h.unregister <- c c.conn.Close() }() for { _, message, err := c.conn.ReadMessage() if err != nil { log.Println("Read fout:", err) break } h.broadcast <- message } } func (c *Client) writePump() { for msg := range c.send { err := c.conn.WriteMessage(websocket.TextMessage, msg) if err != nil { log.Println("Schrijven fout:", err) c.conn.Close() break } } } func main() { h := newHub() go h.run() http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { handleConnections(h, w, r) }) fmt.Println("Server gestart op :8080") err := http.ListenAndServe(":8080", nil) if err != nil { log.Fatal("Server fout:", err) } } ``` ### 3. Client-side voorbeeld (HTML + JavaScript) Voor het testen kun je deze eenvoudige client gebruiken: ```html <!DOCTYPE html> <html lang="nl"> <head> <meta charset="UTF-8" /> <title>WebSocket Chat</title> <script> let socket; function init() { socket = new WebSocket("ws://localhost:8080/ws"); socket.onmessage = function(event) { const chat = document.getElementById("chat"); chat.value += event.data + "\n"; }; } function sendMessage() { const input = document.getElementById("message"); socket.send(input.value); input.value = ""; } window.onload = init; </script> </head> <body> <h2>WebSocket Chat</h2> <textarea id="chat" rows="20" cols="50" readonly></textarea><br /> <input type="text" id="message" /> <button onclick="sendMessage()">Verzend</button> </body> </html> ``` ### Samenvatting - De server gebruikt een `Hub` om alle verbonden clients te beheren en berichten te broadcasten. - Elke client verbindt via `/ws`. - Berichten die door een client worden verzonden, worden via de `broadcast` kanaal naar alle verbonden clients gestuurd. - De client toont berichten in een tekstvak en verzendt berichten via een invoerveld. Met deze opzet heb je een eenvoudige, realtime chattoepassing met WebSocket in Go!
provider: deepseek
model: deepseek-chat
Ik help je graag met het opzetten van WebSocket-communicatie in Go voor een chattoepassing. Hier is een complete uitleg met voorbeeldcode. ## 1. WebSocket Server Setup Eerst installeren we de benodigde package: ```bash go get github.com/gorilla/websocket ``` ### Basis WebSocket Server ```go package main import ( "fmt" "log" "net/http" "github.com/gorilla/websocket" ) // Upgrade de HTTP verbinding naar WebSocket var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true // In productie moet je dit beperken tot specifieke origins }, } // Client vertegenwoordigt een verbonden gebruiker type Client struct { conn *websocket.Conn send chan []byte } // Hub beheert alle verbonden clients type Hub struct { clients map[*Client]bool broadcast chan []byte register chan *Client unregister chan *Client } // Nieuwe Hub initialiseren func newHub() *Hub { return &Hub{ broadcast: make(chan []byte), register: make(chan *Client), unregister: make(chan *Client), clients: make(map[*Client]bool), } } // Hub laten draaien func (h *Hub) run() { for { select { case client := <-h.register: h.clients[client] = true fmt.Println("Nieuwe client verbonden") case client := <-h.unregister: if _, ok := h.clients[client]; ok { delete(h.clients, client) close(client.send) fmt.Println("Client verbinding verbroken") } case message := <-h.broadcast: for client := range h.clients { select { case client.send <- message: default: close(client.send) delete(h.clients, client) } } } } } ``` ## 2. Client Management ```go // Client lezen en schrijven func (c *Client) readPump(hub *Hub) { defer func() { hub.unregister <- c c.conn.Close() }() for { _, message, err := c.conn.ReadMessage() if err != nil { if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) { log.Printf("error: %v", err) } break } // Broadcast bericht naar alle clients hub.broadcast <- message // Log het ontvangen bericht fmt.Printf("Bericht ontvangen: %s\n", string(message)) } } func (c *Client) writePump() { defer func() { c.conn.Close() }() for { select { case message, ok := <-c.send: if !ok { // Hub sluit het kanaal c.conn.WriteMessage(websocket.CloseMessage, []byte{}) return } err := c.conn.WriteMessage(websocket.TextMessage, message) if err != nil { log.Printf("Schrijffout: %v", err) return } } } } ``` ## 3. HTTP Handler voor WebSocket ```go // WebSocket endpoint handler func serveWs(hub *Hub, w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println(err) return } client := &Client{ conn: conn, send: make(chan []byte, 256), } hub.register <- client // Start goroutines voor lezen en schrijven go client.writePump() go client.readPump(hub) } // Serveer statische bestanden (HTML, JS, CSS) func serveHome(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.Error(w, "Niet gevonden", http.StatusNotFound) return } if r.Method != "GET" { http.Error(w, "Method niet toegestaan", http.StatusMethodNotAllowed) return } http.ServeFile(w, r, "home.html") } ``` ## 4. HTML Client Interface Maak een `home.html` bestand: ```html <!DOCTYPE html> <html> <head> <title>Go WebSocket Chat</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } #chat { width: 500px; height: 300px; border: 1px solid #ccc; padding: 10px; overflow-y: scroll; margin-bottom: 10px; } #message { width: 400px; padding: 5px; } button { padding: 5px 15px; } .message { margin: 5px 0; padding: 5px; background: #f0f0f0; border-radius: 5px; } .system { color: #666; font-style: italic; } </style> </head> <body> <h1>Go WebSocket Chat</h1> <div id="chat"></div> <input type="text" id="message" placeholder="Typ je bericht..."> <button onclick="sendMessage()">Versturen</button> <script> let ws = new WebSocket("ws://localhost:8080/ws"); ws.onopen = function() { addMessage("Verbonden met de server", "system"); }; ws.onmessage = function(event) { addMessage(event.data); }; ws.onclose = function() { addMessage("Verbinding verbroken", "system"); }; function addMessage(message, type = "user") { const chat = document.getElementById("chat"); const messageDiv = document.createElement("div"); messageDiv.className = type === "system" ? "message system" : "message"; messageDiv.textContent = message; chat.appendChild(messageDiv); chat.scrollTop = chat.scrollHeight; } function sendMessage() { const input = document.getElementById("message"); const message = input.value.trim(); if (message && ws.readyState === WebSocket.OPEN) { ws.send(message); input.value = ""; } } // Enter toets ondersteuning document.getElementById("message").addEventListener("keypress", function(e) { if (e.key === "Enter") { sendMessage(); } }); </script> </body> </html> ``` ## 5. Hoofdapplicatie ```go package main import ( "log" "net/http" ) func main() { hub := newHub() go hub.run() // HTTP routes http.HandleFunc("/", serveHome) http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { serveWs(hub, w, r) }) // Start server log.Println("Server gestart op http://localhost:8080") err := http.ListenAndServe(":8080", nil) if err != nil { log.Fatal("ListenAndServe: ", err) } } ``` ## 6. Uitgebreide Chat Functionaliteit Voor een completere chat-applicatie kun je JSON berichten gebruiken: ```go // Bericht structuur voor JSON communicatie type Message struct { Username string `json:"username"` Content string `json:"content"` Type string `json:"type"` // "message", "join", "leave" Time string `json:"time"` } // In de readPump functie: func (c *Client) readPump(hub *Hub) { // ... bestaande code ... for { var msg Message err := c.conn.ReadJSON(&msg) if err != nil { break } // Verwerk het bericht op basis van type switch msg.Type { case "join": fmt.Printf("Gebruiker %s is toegetreden\n", msg.Username) case "message": fmt.Printf("Bericht van %s: %s\n", msg.Username, msg.Content) } // Broadcast naar alle clients hub.broadcastJSON(msg) } } ``` ## Gebruik: 1. Sla alle code op in een directory 2. Voer `go mod init chat-app` uit 3. Voer `go get github.com/gorilla/websocket` uit 4. Start de server: `go run main.go hub.go client.go` 5. Open `http://localhost:8080` in meerdere browser tabbladen om te testen Deze implementatie biedt: - Real-time berichtenuitwisseling - Automatische verbindingsbeheer - Schaalbaar client management - Foutafhandeling - Eenvoudige frontend interface Je kunt dit verder uitbreiden met gebruikersauthenticatie, berichtgeschiedenis, kamers, en meer geavanceerde functies.