我开始使用websockets + go and well我认为我在Go中误解了一些非常基本的webockets。
我想简单地听一下websocket连接并进行相应的处理。但是我在Go中使用websocket看到的所有示例都是为连接到websocket的网页提供服务,这是一个要求吗?
以下是我设置的基本回显服务器:
package main
import (
"fmt"
"code.google.com/p/go.net/websocket"
"net/http"
)
func webHandler(ws *websocket.Conn) {
var s string
fmt.Fscan(ws, &s)
fmt.Println("Received: ", s)
}
func main() {
fmt.Println("Starting websock server: ")
http.Handle("/echo", websocket.Handler(webHandler))
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic("ListenAndServe: " + err.Error())
}
}
这是用于连接的javascript:
ws = new WebSocket("ws://localhost:8080/echo");
ws.onmessage = function(e) {
console.log("websock: " + e.data);
};
然而,这导致: 与'ws:// localhost:8080 / echo'的WebSocket连接失败:意外的响应代码:403
答案 0 :(得分:16)
使用Javascript中的websockets时,您很少需要直接读取帧。说实话,我甚至不知道该怎么做。
幸运的是,websocket包已经有了一个类型Codec
,可以为您完成此操作。我的建议是使用预定义的websocket.Message编解码器代替Recieve
和Send
消息。
消息是在WebSocket连接上的帧中发送/接收文本/二进制数据的编解码器。要发送/接收文本框架,请使用字符串类型。要发送/接收二进制帧,请使用[]字节类型。
使用websocket.Message,您的webHandler看起来像这样:
func webHandler(ws *websocket.Conn) {
var in []byte
if err := websocket.Message.Receive(ws, &in); err != nil {
return
}
fmt.Printf("Received: %s\n", string(in))
websocket.Message.Send(ws, in)
}
而且,不,并不要求Go服务于网页。您收到的403错误与Go或websocket包无关。
答案 1 :(得分:10)
我遇到了类似问题,403错误问题与Go如何处理http Origin header有关:
Handler是WebSocket浏览器客户端的简单接口。它默认检查Origin标头是否为有效URL。您可能想验证websocket.Conn.Config()。来自func。如果您使用Server而不是Handler,您可以调用websocket.Origin并检查Handshake func中的原点。因此,如果您想接受不发送Origin标头的非浏览器客户端,您可以使用Server。这不会在握手中检查原点。
要禁用Origin检查,您必须使用以下内容:
http.HandleFunc("/echo",
func (w http.ResponseWriter, req *http.Request) {
s := websocket.Server{Handler: websocket.Handler(webHandler)}
s.ServeHTTP(w, req)
});
至少这解决了我的问题(服务器到服务器WebSocket通信),我认为如果原始标头不匹配,它也可以解决问题。