【问题标题】:Go & Socket.io HTTP + WSS on one port with CORS?Go & Socket.io HTTP + WSS 在一个带有 CORS 的端口上?
【发布时间】:2015-03-05 20:31:13
【问题描述】:

全新的 Go.. 显然仍在学习语法和基础知识.. 但我确实有一个特定的目标..

我正在尝试在 :8080 上建立一个简单的服务器,它可以响应 HTTP 和 socket.io(通过 /socket.io/ url),特别是使用 CORS。

我的代码:

package main

import (
     "log"         
     "net/http"
     "github.com/rs/cors"
     "github.com/googollee/go-socket.io"
 )

 func SayHelloWorld(w http.ResponseWriter, r *http.Request) {
     w.Write([]byte("Hello, World!"))
 }

 func main() {

   c := cors.New(cors.Options{
         AllowedOrigins: []string{"*"},
         AllowCredentials: true,
   })

   server, err := socketio.NewServer(nil)
     if err != nil {
         log.Fatal(err)
     }


   server.On("connection", func(so socketio.Socket) {
      log.Println("on connection")
      so.Join("chat")
      so.On("chat message", func(msg string) {
          log.Println("emit:", so.Emit("chat message", msg))
          so.BroadcastTo("chat", "chat message", msg)
      })
      so.On("disconnection", func() {
          log.Println("on disconnect")
      })
   })

   server.On("error", func(so socketio.Socket, err error) {
      log.Println("error:", err)
   })    


   http.Handle("/socket.io/", c.Handler(server))
   http.HandleFunc("/", SayHelloWorld)
   log.Println("Serving at localhost:8080...")
   log.Fatal(http.ListenAndServe(":8080", nil))
}

在客户端我仍然看到:

到 'wss://api.domain.com/socket.io/?EIO=3&transport=websocket&sid=xNWd9aZvwDnZOrXkOBaC' 的 WebSocket 连接失败:在建立连接之前 WebSocket 已关闭。

(index):1 XMLHttpRequest 无法加载 https://api.domain.com/socket.io/?EIO=3&transport=polling&t=1420662449235-3932&sid=xNWd9aZvwDnZOrXkOBaC。请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin 'http://fiddle.jshell.net' 因此不允许访问。

编辑 #1:

所以我一直在拼命试图理解为什么我无法连接.. 遇到了一个更令人困惑的难题?

https://gist.github.com/acoyfellow/167b055da85248c94fc4

上面的要点是我的golang服务器的代码+用于连接的浏览器代码..这段代码将每秒向后端发送30个HTTP GET请求,无需连接、升级或给予任何错误(客户端或服务器端).. 它本质上 DDOS 是我自己的后端?

有人,请有人告诉我我在做一些愚蠢的事情。这真是个泡菜:P

编辑 #2:

我可以通过简单地调整 Go 中 socket.io 端点 URL 上的尾随 / 来停止“DDOS”。所以:mux.Handle("/socket.io", server)mux.Handle("/socket.io/", server) 现在将产生错误消息和连接尝试错误回应:

到“wss://api.domain.com/socket.io/?EIO=3&transport=websocket&sid=0TzmTM_QtF1TaS4exiwF”的 WebSocket 连接失败:WebSocket 握手期间出错:意外响应代码:400 socket.io-1.2.1。 js:2

GET https://api.domain.com/socket.io/?EIO=3&transport=polling&t=1420743204485-62&sid=0TzmTM_QtF1TaS4exiwF 400(错误请求)

【问题讨论】:

    标签: go websocket socket.io cors


    【解决方案1】:

    你的意思是 http + ws 还是 https + wss。如果你从 wss 中删除一个 s,你应该能够连接。

    如果你想要 tls 用于 web socket (wss),那么你需要 http.ListenAndServeTLS。

    【讨论】:

    • 这应该是评论,而不是答案。已投票,因此您现在可以拥有评论权限。
    【解决方案2】:

    所以我放弃了使用 googoolee 的 Socket.io 实现,而使用了 gorilla 的。

    我查看了他们的示例:https://github.com/gorilla/websocket/tree/master/examples/chat

    查看他们的文档:http://www.gorillatoolkit.org/pkg/websocket -- 在我发现的 Origin Considerations 下:

    应用程序可以通过指定一个始终返回 true 的函数来允许来自任何来源的连接:

    var upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, }

    我在他们的示例中将这个 CheckOrigin 函数添加到了 conn.go 文件中,并且能够让 CORS 套接字服务器与浏览器通信。

    作为对 Golang 的第一次冒险,这既令人沮丧又有趣.. +1 其他学习者

    【讨论】:

      【解决方案3】:

      似乎 CORS 不适用于 WebSocket。根据这个相关问题“使用 WebSocket,有一个“原点”标头,浏览器必须填充包含打开 WS 连接的 JS 的 HTML 的原点。”

      如此处所述: Cross origin websockets with Golang

      【讨论】:

      • 嗯.. 我无法解释您的答案(以及链接的答案)。我已经有一个 Node.js/Socket.io 集群,它在 CORS 上使用 websockets 没问题,所以现在我更加困惑了。听起来你说我需要将我的来源从客户端发送到 socket.io 服务器,但我不明白。它不会自动填充吗?我在 Socket.io 客户端 API 中看不到任何关于明确设置来源的内容
      【解决方案4】:

      我在正常的 ajax 调用中遇到了类似的问题。它需要在前端和后端进行更多的工作。我相信最流行的前端库如 JQuery 或 AngularJS 可以很好地处理这些。
      我看到你正在使用 https://github.com/rs/cors 包,但你没有包括该包的使用,这里是只有 Go std 包的工具:

      type CrossOriginServer struct {}
      
      func (s *CrossOriginServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
          // you may need to add some more headers here
          allowHeaders := "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization"
          if origin := req.Header.Get("Origin"); validOrigin(origin) {
              rw.Header().Set("Access-Control-Allow-Origin", origin)
              rw.Header().Set("Access-Control-Allow-Methods", "POST, PUT, PATCH, GET, DELETE")
              rw.Header().Set("Access-Control-Allow-Headers", allowHeaders)
          }
          if req.Method == "OPTIONS" {
              return
          }
      
          // if you want, you can use gorilla/mux or any routing package here
          mux := http.NewServeMux()
          mux.Handle("/socket.io/", c.Handler(server))
          mux.HandleFunc("/", SayHelloWorld)
      
          mux.ServeHTTP(rw, req)
      }
      
      func validOrigin(origin string) bool {
          allowOrigin := []string{
              "http://localhost:8081",
              "http://example.com"
          }
      
          for _, v := range allowOrigin {
              if origin == v {
                  return true
              }
          }
      
          return false
      }
      
      func main() {
          // do you stuff
          // ...
          // ...
      
          http.ListenAndServe(":8080", &CrossOriginServer{})
      }
      

      【讨论】:

      • 感谢您的回复,我现在正在尝试您的解决方案。作为旁注,我很困惑你为什么提到我没有使用 cors 包。@ 987654324@ 是@ 987654325@ 下的第一块代码——我用错了吗?
      • 我已经在这里尝试了您的解决方案,但没有运气.. (gist.github.com/acoyfellow/72cfc18acb2f0eee0b96) 但我仍然要么:A)重复我同样的错误或 B)做其他错误。
      【解决方案5】:

      在你的SayHelloWorld func 中添加如下内容怎么样:

      w.Header().Set("Access-Control-Allow-Origin", "*")
      

      或者,可能更好:

      if origin := r.Header.Get("Origin"); origin != "" {
        w.Header().Set("Access-Control-Allow-Origin", origin)
      }
      

      【讨论】:

      • 感谢您的提示,但我尝试了但没有运气。客户端中的错误响应相同。连接,然后断开连接,说明:closed before the connection is established. (index):1 XMLHttpRequest cannot load https://api.domain.com/socket.io/?... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access.
      猜你喜欢
      • 2014-02-28
      • 2022-01-14
      • 2016-07-11
      • 2015-04-28
      • 1970-01-01
      • 1970-01-01
      • 2023-01-14
      • 2014-04-22
      • 1970-01-01
      相关资源
      最近更新 更多