英文:
websocket: the client is not using the websocket protocol: 'upgrade' token not found in 'Connection' header
问题
我正在尝试在使用Go编写的服务器和JavaScript前端之间建立WebSocket连接。我在一个目录中有以下文件:
main.go
index.html
以下是我在main.go
中的Go代码:
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
func homePage(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./index.html")
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Error in handler:", err)
return
}
log.Println("Client connected.")
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
log.Println("Fehler in ReadMessage:", err)
return
}
log.Println(string(p))
//echo message to client
if err := conn.WriteMessage(messageType, p); err != nil {
log.Println(err)
return
}
}
}
func setupRoutes() {
http.HandleFunc("/ws", homePage)
}
func main() {
fmt.Println("Server gestartet")
setupRoutes()
log.Fatal(http.ListenAndServe(":9100", nil))
}
以下是index.html
中的HTML和JavaScript代码:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Some unimportant html </title>
</head>
<body>
<script>
let socket = new WebSocket("ws://localhost:9100/ws");
console.log("Websocket started.");
socket.onOpen = () => {
console.log("Client started.");
}
socket.onclose = (event) => {
console.log("Socket closed: ", event);
}
socket.onError = (error) => {
console.log("Socket Error: ", error);
}
socket.onMessage = (msg) => {
console.log(msg);
}
</script>
</body>
</html>
然而,当我使用go run main.go
运行时,我得到以下错误:
2022/11/20 16:38:33 http: superfluous response.WriteHeader call from github.com/gorilla/websocket.(*Upgrader).returnError (server.go:83)
2022/11/20 16:38:33 Error in handler: websocket: the client is not using the websocket protocol: 'upgrade' token not found in 'Connection' header
2022/11/20 16:38:33 Error in handler: write tcp [::1]:9100->[::1]:63712: wsasend: Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen.
2022/11/20 16:39:06 Error in handler: write tcp [::1]:9100->[::1]:63733: wsasend: Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen.
exit status 0xc000013a
德语部分的意思是“现有连接被主机计算机软件控制终止”。
我可能遗漏了一些东西,我的理解不够深入,无法确定问题出在哪里。非常感谢任何帮助!
我想也许我的JS WebSocket缺少升级,但是在Chrome中,我可以看到请求URL ws://localhost:9100/ws 的请求头,其中包含“Upgrade: websocket”:
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: no-cache
Connection: Upgrade
Host: localhost:9100
Origin: http://localhost:9100
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: h3DWLuXsI9/GkTo+sIjyzw==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
英文:
I am trying to set up a websocket connection with the server written in Go and a JavaScript frontend. I have the following files in one directory:
main.go
index.html
**This is my Go code in main.go
: **
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
func homePage(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./index.html")
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Error in handler:", err)
return
}
log.Println("Client connected.")
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
log.Println("Fehler in ReadMessage: ", err)
return
}
log.Println(string(p))
//echo message to client
if err := conn.WriteMessage(messageType, p); err != nil {
log.Println(err)
return
}
}
}
func setupRoutes() {
http.HandleFunc("/ws", homePage)
}
func main() {
fmt.Println("Server gestartet")
setupRoutes()
log.Fatal(http.ListenAndServe(":9100", nil))
}
And this is the HTML and JavaScript in index.html:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Some unimportant html </title>
</head>
<body>
<script>
let socket = new WebSocket("ws://localhost:9100/ws");
console.log("Websocket started.");
socket.onOpen = () => {
console.log("Client started.");
}
socket.onclose = (event) => {
console.log("Socket closed: ", event);
}
socket.onError = (error) => {
console.log("Socket Error: ", error);
}
socket.onMessage = (msg) => {
console.log(msg);
}
</script>
</body>
</html>
However, when I run the thing with go run main.go
I get the following error:
2022/11/20 16:38:33 http: superfluous response.WriteHeader call from github.com/gorilla/websocket.(*Upgrader).returnError (server.go:83)
2022/11/20 16:38:33 Error in handler: websocket: the client is not using the websocket protocol: 'upgrade' token not found in 'Connection' header
2022/11/20 16:38:33 Error in handler: write tcp [::1]:9100->[::1]:63712: wsasend: Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen.
2022/11/20 16:39:06 Error in handler: write tcp [::1]:9100->[::1]:63733: wsasend: Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen.
exit status 0xc000013a
The German lines mean "the existing connection was software controlled terminated by the host computer"
I am missing something and my understanding doesn't run deep enough to pinpoint what's wrong. Any help is much appreciated!
I thought maybe my JS Websocket is missing an upgrade, but in Chrome I can see the following request header for Request URL ws://localhost:9100/ws that says "Upgrade:websocket"
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: no-cache
Connection: Upgrade
Host: localhost:9100
Origin: http://localhost:9100
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: h3DWLuXsI9/GkTo+sIjyzw==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
答案1
得分: 1
感谢Cerise Limón的有用评论,我成功修复了它。问题是我需要一个用于索引文件的端点,另一个用于websocket。所以我将相关部分更改为以下内容:
func websocketHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil) //conn是一个websocket连接(从http转换为websocket协议)
if err != nil {
log.Println("处理程序中的错误:", err)
return
}
log.Println("客户端已连接。")
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
log.Println("ReadMessage中的错误:", err)
return
}
log.Println(string(p))
//将消息回显给客户端
if err := conn.WriteMessage(messageType, p); err != nil {
log.Println(err)
return
}
}
}
func homePage(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./index.html")
}
func setupRoutes() {
http.HandleFunc("/", homePage)
http.HandleFunc("/ws", websocketHandler)
}
英文:
Thanks to the helpful comment by Cerise Limón I was able to fix it. The problem was that I needed one endpoint for the index file and another one for the websocket. So I changed the relevant parts to this:
func websocketHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil) //conn is a websocket connection (aus http wird websocket protokoll)
if err != nil {
log.Println("Error in handler:", err)
return
}
log.Println("Client connected.")
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
log.Println("Fehler in ReadMessage: ", err)
return
}
log.Println(string(p))
//echo message to client
if err := conn.WriteMessage(messageType, p); err != nil {
log.Println(err)
return
}
}
}
func homePage(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./index.html")
}
func setupRoutes() {
http.HandleFunc("/", homePage)
http.HandleFunc("/ws", websocketHandler)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论