使用相同的处理程序处理websocket和HTTP

Been scouring for a while but couldn't find anything that directly answers this.

Can Go handle WS connections and HTTP connections using the same handler?

In short, I'd like to replicate something like SignalR

Yes, the gorilla/websocket package supports upgrade from HTTP to WebSocket in a request handler. See the example at the beginning of the package documentation. The function handler is a standard HTTP request handler. The call to upgrader.Upgrade switches the connection to the WebSocket protocol.

The x/net/websocket package requires a separate handler. There are other reasons why you probably don't want to use the x/net/websocket package.

I ended up needing to filter the request myself before passing it to upgrader.upgrade method. Because upgrader.upgrade, upon failing to upgrade the request, write 'Bad request' response to it. Something that will render my HTML as plain text with additional 'Bad request' text in the beginning.

So this is what I do at the top of the 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
    }

    ...
}

Here is an example repo: https://github.com/siriusdely/gochat. Based on Andrew Gerrand's talk: code that grows with grace https://talks.golang.org/2012/chat.slide#44.