使用相同的处理程序去处理 websockets 和 HTTP
Posted
技术标签:
【中文标题】使用相同的处理程序去处理 websockets 和 HTTP【英文标题】:Go handling websockets and HTTP with the same handler 【发布时间】:2014-12-10 19:30:17 【问题描述】:已经搜索了一段时间,但找不到直接回答这个问题的任何东西。
Go 能否使用同一个处理程序来处理 WS 连接和 HTTP 连接?
简而言之,我想复制 SignalR 之类的东西
【问题讨论】:
您希望如何在服务器上从 websocket“降级”到 http?客户端正在请求 websocket,或者不是。 抱歉,我发帖后才发现,没有及时编辑。我知道用于确定浏览器功能的客户端工具。我已将我的问题编辑为特定于服务器端。 gorillatoolkit.org/pkg/websocket 似乎暗示答案是“是”。Upgrader.Upgrade()
将返回 nil
错误,如果它可以将协议升级到 websockets,所以你可以检查这种情况。
我也发现了这个 -talks.golang.org/2012/chat.slide#30 - 我只是不想有重复的 WS 和 HTTP 处理程序
【参考方案1】:
是的,gorilla/websocket 包支持在请求处理程序中从 HTTP 升级到 WebSocket。请参阅beginning of the package documentation 中的示例。函数handler
是一个标准的HTTP 请求处理程序。对upgrader.Upgrade
的调用将连接切换到WebSocket 协议。
x/net/websocket 包需要单独的处理程序。有other reasons为什么你可能不想使用 x/net/websocket 包。
【讨论】:
【参考方案2】:在将请求传递给upgrader.upgrade
方法之前,我最终需要自己过滤请求。因为upgrader.upgrade
,在升级请求失败时,写'Bad request' 响应给它。将我的 html 呈现为纯文本,并在开头附加“错误请求”文本。
这就是我在handler
顶部所做的:
func singleHandler(w http.ResponseWriter, r *http.Request)
upgrade := false
for _, header := range r.Header["Upgrade"]
if header == "websocket"
upgrade = true
break
if upgrade == false
if r.Method != "GET"
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
if r.URL.Path != "/"
http.NotFound(w, r)
return
chatTemplate.Execute(w, listenAddr)
return
c, err := upgrader.Upgrade(w, r, nil)
if err != nil
log.Print("Upgrade err:", err)
return
...
这是一个示例 repo:https://github.com/siriusdely/gochat。基于 Andrew Gerrand 的演讲:优雅成长的代码 https://talks.golang.org/2012/chat.slide#44。
【讨论】:
以上是关于使用相同的处理程序去处理 websockets 和 HTTP的主要内容,如果未能解决你的问题,请参考以下文章
在调用处理程序之前使用 Tomcat 8 和 Spring 4 ClassCastException 的 websockets
使用 React、Redux 和 Websocket 处理请求