13

I'm starting to play around with websockets + go and well I think I'm misunderstanding something quite basic with websockets in Go.

I'd like to simply listen for a websocket connection and process accordingly. However all examples I see in Go using websocket is serving the web page that then connects to the websocket, is this a requirement?

The following is a basic echo server I have setup:

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())
  }
}

This is the javascript used to connect:

ws = new WebSocket("ws://localhost:8080/echo");
ws.onmessage = function(e) {
    console.log("websock: " + e.data);
};

However this results in: WebSocket connection to 'ws://localhost:8080/echo' failed: Unexpected response code: 403

4

2 回答 2

16

从 Javascript 使用 websocket 时,您很少需要直接读取帧。老实说,我什至不知道该怎么做。

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

Message 是一种编解码器,用于在 WebSocket 连接的帧中发送/接收文本/二进制数据。要发送/接收文本框,请使用字符串类型。要发送/接收二进制帧,请使用 []byte 类型。

使用 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 包无关。

于 2013-10-31T14:21:30.290 回答
11

我有一个类似的问题,403 错误问题与 Go 如何处理http Origin 标头有关:

Handler 是 WebSocket 浏览器客户端的简单接口。默认情况下,它检查 Origin 标头是否是有效的 URL。您可能想在 func 中验证 websocket.Conn.Config().Origin。如果您使用 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 通信),我认为如果源头不匹配,它也可以解决问题。

于 2014-04-27T13:56:59.590 回答