去&在一个端口上使用CORS的Socket.io HTTP + WSS?

时间:2015-01-07 20:26:49

标签: go websocket socket.io cors

全新的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))
}

在客户端,我仍然看到:

  

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

     

(index):1 XMLHttpRequest无法加载https://api.domain.com/socket.io/?EIO=3&transport=polling&t=1420662449235-3932&sid=xNWd9aZvwDnZOrXkOBaC。请求的资源上不存在“Access-Control-Allow-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)现在会产生错误消息和连接尝试的错误响应为:

  

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

     

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

5 个答案:

答案 0 :(得分:4)

所以我放弃了使用googoolee的Socket.io实现并与大猩猩一起去了。

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

查看了他们的文档:http://www.gorillatoolkit.org/pkg/websocket - 根据原因考虑我发现:

  

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

     

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

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

作为Golang的第一次冒险,这是令人沮丧和有趣的.. +1给其他人学习

答案 1 :(得分:3)

不是指http + ws或https + wss。如果从wss中删除s,则应该能够连接。

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

答案 2 :(得分:1)

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

如上所述: Cross origin websockets with Golang

答案 3 :(得分:0)

在你的SayHelloWorld功能中添加如下内容:

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

或者,可能更好:

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

答案 4 :(得分:0)

我通过正常的ajax调用获得类似的问题。它需要在前端和后端进行更多的工作。我相信最流行的前端libs谎言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{})
}