I have a Go web server running on my localhost. I'm using Nginx as a reverse proxy to change the protocol to ws
when a certain route is accessed on my server.
I keep getting this error message in my browser - (index):13 WebSocket connection to 'ws://127.0.0.1:8080/ws' failed: Connection closed before receiving a handshake response
In addition, the Go server keeps printing this error - read tcp [::1]:8080->[::1]:59967: read: connection reset by peer
I've tried a number of combinations in my nginx.conf file. I can't seem to get any of them to work.
Go:
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/websocket"
)
func reader(conn *websocket.Conn) {
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
log.Println(err)
return
}
fmt.Println(string(p))
if err := conn.WriteMessage(messageType, p); err != nil {
log.Println(err)
return
}
}
}
func homePage(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Home Page")
}
func wsEndpoint(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
if err != nil {
http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
log.Println(err)
return
}
log.Println("Client Connected")
err = ws.WriteMessage(1, []byte("Hi Client!"))
if err != nil {
log.Println("Error")
log.Println(err)
return
}
reader(ws)
}
func setupRoutes() {
http.HandleFunc("/", homePage)
http.HandleFunc("/ws", wsEndpoint)
}
func main() {
fmt.Println("Hello World")
setupRoutes()
log.Fatal(http.ListenAndServe(":8080", nil))
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Go WebSocket Tutorial</title>
</head>
<body>
<h2>Hello World</h2>
<script>
let socket = new WebSocket("ws://127.0.0.1:8080/ws");
console.log("Attempting Connection...");
socket.onopen = () => {
console.log("Successfully Connected");
socket.send("Hi From the Client!");
};
socket.onmessage = msg => {
console.log(msg);
};
socket.onclose = event => {
console.log("Socket Closed Connection: ", event);
socket.send("Client Closed!");
};
socket.onerror = error => {
console.log("Socket Error: ", error);
};
</script>
</body>
</html>
nginx.conf
{
server {
listen 8080;
server_name localhost;
location /ws {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:8080/ws;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {
# root html;
# index index.html index.htm;
proxy_pass http://localhost:8080;
}
}
I'm expecting the websocket connection to stay open indefinitely. I don't know what exactly is closing it and why.
Any suggestions on what I'm doing wrong are much appreciated.