英文:
Websocket handshake fails 404 (golang server)
问题
我有一个简单的Go Web服务器,它在localhost:8080端口上提供一个包含HTML文件和客户端脚本(带有WebSocket逻辑)的public文件夹。
在我的main.go文件中:
listener, err := net.listen("tcp", "localhost:8080")
if err != nil {
log.Fatal(err)
}
// 完整的代码在此处:https://gist.github.com/Kielan/98706aaf5dc0be9d6fbe
然后在我的客户端脚本中:
try {
var sock = new WebSocket("ws://127.0.0.1:8080");
console.log("Websocket - status: " + sock.readyState);
sock.onopen = function(message) {
console.log("CONNECTION opened..." + this.readyState);
// onmessage, onerr, onclose, 等等...
}
}
我在Chrome中遇到了以下错误:
WebSocket connection to 'ws://127.0.0.1:8080/' failed: Error during WebSocket handshake: Unexpected response code: 200
以及在Firefox中:
Firefox can't establish a connection to the server at ws://127.0.0.1:8080/.
我在这篇文章中找到了关于Node.js的信息,它指出需要在客户端的WebSocket字符串中添加/websocket
,但这并没有解决问题,反而导致了404错误。
我原以为响应代码200是好的,难道我需要以某种方式将请求转换为WebSocket,并且可能默认为HTTP吗?如果是这样,我应该如何做到这一点?
英文:
I have a simple go web server which serves on port localhost:8080 an public folder containing both an html file as well as a client script with websocket logic.
in my main.go file
listener, err := net.listen("tcp", "localhost:8080")
if err != nil {
log.Fatal(err)
}
//full code in gist https://gist.github.com/Kielan/98706aaf5dc0be9d6fbe
then in my client script
try {
var sock = new WebSocket("ws://127.0.0.1:8080");
console.log("Websocket - status: " + sock.readyState);
sock.onopen = function(message) {
console.log("CONNECTION opened..." + this.readyState);
//onmessage, onerr, onclose, ect...
}
I get the error in chrome
WebSocket connection to 'ws://127.0.0.1:8080/' failed: Error during WebSocket handshake: Unexpected response code: 200
and Firefox
Firefox can't establish a connection to the server at ws://127.0.0.1:8080/.
I found this article referring to node.js indicating to add /websocket to my client websocket string, though it did not solve the problem and resulted in a 404
I thought response code 200 is good, do I need to convert the request to a websocket somehow and maybe it is defaulting to http? If so how can I do this?
答案1
得分: 1
像JimB指出的那样,你还没有处理HTTP和WebSocket连接。
你可以使用github.com/gorilla/websocket
包来处理WebSocket连接。一个简单的设置如下所示:
package main
import (
"log"
"net/http"
"github.com/gorilla/websocket"
)
// wsHandler 实现了 Handler 接口
type wsHandler struct{}
func main() {
router := http.NewServeMux()
router.Handle("/", http.FileServer(http.Dir("./webroot"))) // 处理位于 ./webroot 下的静态 HTML / CSS 等文件
router.Handle("/ws", wsHandler{}) // 处理 WebSocket 连接
// 启动服务
log.Fatal(http.ListenAndServe("localhost:8080", router))
}
func (wsh wsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// upgrader 用于将 HTTP 连接升级为 WebSocket 连接
upgrader := &websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
// 将 HTTP 连接升级为 WebSocket 连接
wsConn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Printf("升级连接时出错:%s", err)
return
}
// 使用 wsConn 处理你的 WebSocket
}
然后在你的 JavaScript 中,你需要使用 var sock = new WebSocket("ws://localhost/ws:8080");
。
英文:
Like JimB pointed out, you are not handling http nor websocket connections yet.
You can do websocket handling with the package github.com/gorilla/websocket
This is how a simple setup could look like:
package main
import (
"log"
"net/http"
"github.com/gorilla/websocket"
)
// wsHandler implements the Handler Interface
type wsHandler struct{}
func main() {
router := http.NewServeMux()
router.Handle("/", http.FileServer(http.Dir("./webroot"))) //handles static html / css etc. under ./webroot
router.Handle("/ws", wsHandler{}) //handels websocket connections
//serving
log.Fatal(http.ListenAndServe("localhost:8080", router))
}
func (wsh wsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// upgrader is needed to upgrade the HTTP Connection to a websocket Connection
upgrader := &websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
//Upgrading HTTP Connection to websocket connection
wsConn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Printf("error upgrading %s", err)
return
}
//handle your websockets with wsConn
}
In your Javascript you then need var sock = new WebSocket("ws://localhost/ws:8080");
obviously.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论