使用Go实现WebSocket时遇“WebSocket: response does not implement HTTP.Hijacker”错误求助
Hey there! Let's walk through why you're seeing this error and how to fix it. I remember running into this exact issue when I was starting out with Go WebSockets too, so I feel your pain.
What's causing this error?
The gorilla/websocket Upgrader needs the underlying http.ResponseWriter to implement the http.Hijacker interface—this is how it "hijacks" the HTTP connection to switch it over to the WebSocket protocol. The error pops up when the ResponseWriter you're passing to upgrader.Upgrade() doesn't have this interface implemented.
The most common scenarios for this are:
- You're using a custom middleware that wraps the original
ResponseWriterbut doesn't pass through theHijackmethod. - You're running your code in an environment that uses a mock or stripped-down
ResponseWriter(like some testing tools that don't support hijacking). - You've accidentally modified or replaced the original
ResponseWritersomewhere in your request chain.
Let's check your code and fix it
First, your upgrader and HandleConnections function look perfectly fine—no issues there! The problem is likely in how you're registering this handler or what middleware you're using before it.
Solution 1: Verify your server setup
Make sure you're registering the handler directly with the standard HTTP server without any incompatible middleware. Here's a full working example that should work:
package main import ( "log" "net/http" "github.com/gorilla/websocket" ) var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, CheckOrigin: func(r *http.Request) bool { return true // Safe for development; restrict this in production! }, } func HandleConnections(w http.ResponseWriter, r *http.Request) { ws, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println("Upgrade error:", err) return } log.Println("Hello client!") defer ws.Close() // Add your WebSocket read/write logic here } func main() { // Register the handler directly with the standard server http.HandleFunc("/ws", HandleConnections) log.Println("Server starting on :8080...") log.Fatal(http.ListenAndServe(":8080", nil)) }
Solution 2: Fix middleware that wraps ResponseWriter
If you're using middleware that wraps http.ResponseWriter, you need to make sure your wrapper implements the http.Hijacker interface and delegates to the original writer. For example:
import ( "bufio" "net" "net/http" ) // Custom response writer wrapper type wrappedResponseWriter struct { http.ResponseWriter } // Implement Hijack to pass through to the original writer func (w *wrappedResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { hijacker, ok := w.ResponseWriter.(http.Hijacker) if !ok { return nil, nil, http.ErrNotSupported } return hijacker.Hijack() } // Example middleware using the wrapper func myMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { wrapped := &wrappedResponseWriter{w} next.ServeHTTP(wrapped, r) }) }
This way, when the WebSocket upgrader tries to hijack the connection, it can still access the original implementation.
Solution 3: Testing considerations
If you're hitting this in tests, note that the default httptest.ResponseRecorder doesn't support Hijack. For WebSocket tests, use the gorilla/websocket test utilities or create a mock response writer that implements Hijacker.
Final notes
- In production, don't leave
CheckOriginreturningtrue—restrict it to your allowed domains to prevent CSRF attacks. - Make sure you're using the latest version of gorilla/websocket: run
go get github.com/gorilla/websocket@latestto update.
内容的提问来源于stack exchange,提问作者Yuvaraj kumar

