在Go中提供websocket

时间:2013-10-31 13:49:19

标签: websocket go

我开始使用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

2 个答案:

答案 0 :(得分:16)

使用Javascript中的websockets时,您很少需要直接读取帧。说实话,我甚至不知道该怎么做。

幸运的是,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)      
}

而且,不,并不要求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通信),我认为如果原始标头不匹配,它也可以解决问题。