Mark Walsh
Mark Walsh

Reputation: 3361

Go handling websockets and HTTP with the same handler

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

Upvotes: 2

Views: 3291

Answers (2)

siriusdely
siriusdely

Reputation: 149

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.

Upvotes: 3

user4122236
user4122236

Reputation:

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.

Upvotes: 3

Related Questions