2013-10-31 31 views
11

我开始使用websockets + go了,我觉得我误解了Go的websockets中的一些基本的东西。在Go服务websocket

我想简单地听一个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); 
}; 

然而,这导致: WebSocket连接到“WS://localhost:8080/echo'失败:意外的响应代码:403

回答

15

当使用JavaScript的websockets时,您很少必须阅读框架可怕ctly。说实话,我甚至不知道该怎么做。

幸运的是,websocket包已经有了一个类型,Codec可以为你做到这一点。我的建议是使用预定义的websocket.Message编解码器来代替RecieveSend消息。

消息是在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)  
} 

而且,不,它不是去服务于网页上的要求。您收到的403错误与Go或websocket包无关。

+0

if区块中断是什么意思? –

+1

@ElgsQianChen中断最有可能是我首先将接收和发送放在for-loop中的残余,以防止它在第一条消息之后断开连接。我已将它改为“return”。 – ANisus

+0

啊,我明白了。感谢@ANisus的解释。 –

10

我也有类似的问题,403错误问题是关系到如何去对待http Origin header

处理程序是一个简单的界面到WebSocket浏览器客户端。它会默认检查Origin标题是否为有效的URL。你可能想要验证websocket.Conn.Config()。如果您使用服务器而不是处理程序,则可以调用websocket.Origin并检查握手函数中的原点。因此,如果您想接受不发送Origin头的非浏览器客户端,则可以使用Server。在握手中不检查原点。

为了禁用源检查,你必须使用类似:

http.HandleFunc("/echo", 
    func (w http.ResponseWriter, req *http.Request) { 
     s := websocket.Server{Handler: websocket.Handler(webHandler)} 
     s.ServeHTTP(w, req) 
    }); 

根本上解决了这个问题对我来说(服务器到服务器的WebSocket通讯),我认为这可以解决这个问题至少以及如果原始标题不匹配。

+0

我正在寻找一种禁用交叉原点检查的方法。 src/ondemand/server.go:103:不能使用func文字(类型func(http.ResponseWriter,* http.Request))作为类型http.Handler参数http.Handle: \t func(http.ResponseWriter,* http .Request)不执行http.Handler(缺少ServeHTTP方法) – coulix

+0

该死的,谢谢!这个解决方案不仅可以工作,而且适用于我已有的! –