登录
首页 >  Golang >  Go问答

在 Go 中升级后保持 WebSocket 连接处于活动状态

来源:stackoverflow

时间:2024-02-11 23:30:28 192浏览 收藏

小伙伴们对Golang编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《在 Go 中升级后保持 WebSocket 连接处于活动状态》,就很适合你,本篇文章讲解的知识点主要包括。在之后的文章中也会多多分享相关知识点,希望对大家的知识积累有所帮助!

问题内容

我在保持 websocket 连接处于活动状态时遇到问题。在下面的代码中,我分配了 2 个不同的端口来处理 websocket (:8080) 和 api 请求 (:3300)。

当我直接使用 websocket 处理程序时没有问题,但使用 api 处理程序请求并向 websocker 处理程序发出新的外部请求时,连接直接关闭。如有任何帮助,我们将不胜感激。

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "net/http"
    "time"

    "github.com/gobwas/ws"
    "github.com/gobwas/ws/wsutil"
)

func main() {
    go websocket()

    http.HandleFunc("/ws", func(rw http.ResponseWriter, r *http.Request) {

        body, err := ioutil.ReadAll(r.Body)
        if err != nil {
            http.Error(rw, err.Error(), http.StatusInternalServerError)
            return
        }

        url := fmt.Sprintf("http://127.0.0.1:8080?%s", r.URL.RawQuery)
        req, err := http.NewRequest(r.Method, url, bytes.NewReader(body))

        if err != nil {
            fmt.Println(err)
            panic(err)
        }

        req.Header = make(http.Header)
        for h, val := range r.Header {
            req.Header[h] = val
        }

        httpClient := &http.Client{Timeout: time.Second * 10}
        httpClient.Do(req)

    })

    http.ListenAndServe(":3300", nil)
}

func websocket() {
    http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        conn, _, _, err := ws.UpgradeHTTP(r, w)
        if err != nil {
            fmt.Println(err)
            return
        }

        go func() {
            defer conn.Close()

            for {
                msg, op, err := wsutil.ReadClientData(conn)

                if err != nil {
                    fmt.Println(err)
                    return
                }
                err = wsutil.WriteServerMessage(conn, op, msg)
                if err != nil {
                    fmt.Println(err)
                    return
                }
            }
        }()
    }))
}

解决方案


问题中的代码使用 http 请求连接到 websocket 端点。结果升级失败。

使用标准库reverse proxy来代理请求。

更简单的方法是直接调用 websocket 处理程序。将处理程序移至顶级函数:

func handlews(w http.responsewriter, r *http.request) {
    conn, _, _, err := ws.upgradehttp(r, w)
    if err != nil {
        fmt.println(err)
        return
    }

    go func() {
        defer conn.close()

        for {
            msg, op, err := wsutil.readclientdata(conn)

            if err != nil {
                fmt.println(err)
                return
            }
            err = wsutil.writeservermessage(conn, op, msg)
            if err != nil {
                fmt.println(err)
                return
            }
        }
    }()
}

在两个服务器中使用处理程序。

func main() {
    go websocket()
    http.HandleFunc("/ws", handleWS)
    http.ListenAndServe(":3300", nil)
}

func websocket() {
    http.ListenAndServe(":8080", http.HandlerFunc(handleWS))
}

理论要掌握,实操不能落!以上关于《在 Go 中升级后保持 WebSocket 连接处于活动状态》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>