首页 > 后端开发 > Golang > 正文

Go WebSocket 如何处理并发连接?

PHPz
发布: 2024-06-04 09:02:00
原创
976 人浏览过

Go WebSocket 处理并发连接的方法:为每个连接使用一个 Goroutine。通过 Channel 进行连接通信。使用第三方库(如 [gowebsocket](https://github.com/gobwas/ws)、[gorilla/websocket](https://github.com/gorilla/websocket))来简化处理。

Go WebSocket 如何处理并发连接?

Go WebSocket 如何处理并发连接

WebSocket 是一种全双工通信协议,允许客户端和服务器进行实时双向通信。Go 语言中处理 WebSocket 并发连接的常用方法如下:

1. Goroutine

一个简单的解决方案是为每个连接使用一个 Goroutine。Goroutine 是 Go 中的一种轻量级线程,可以并行执行。当一个新的 WebSocket 连接建立时,我们可以创建一个新的 Goroutine 来处理它:

package main

import (
    "fmt"
    "net/http"
    "os"

    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{}

func main() {
    // WebSocket 服务器端口号
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        // 对请求进行 WebSocket 升级
        conn, err := upgrader.Upgrade(w, r, nil)
        if err != nil {
            fmt.Println(err)
            return
        }

        // 创建一个 Goroutine 处理连接
        go handleConnection(conn)
    })

    http.ListenAndServe(":"+port, nil)
}

// handleConnection 处理一个 WebSocket 连接
func handleConnection(conn *websocket.Conn) {
    for {
        msgType, msg, err := conn.ReadMessage()
        if err != nil {
            fmt.Println(err)
            break
        }

        if msgType == websocket.TextMessage {
            // 处理文本消息
            fmt.Println("Received text message:", string(msg))
            if err := conn.WriteMessage(msgType, msg); err != nil {
                fmt.Println(err)
            }
        } else {
            // 处理其他类型的消息
        }
    }

    conn.Close()
}
登录后复制

2. Channel

Channel 是 Go 中用于通信的并发通道。我们可以通过一个 Channel 来处理多个连接:

package main

import (
    "fmt"
    "net/http"
    "os"
    "sync"
    "time"

    "github.com/gorilla/websocket"
)

var (
    upgrader = websocket.Upgrader{}
    connections = make(chan *websocket.Conn, 100)
    wg sync.WaitGroup
)

func main() {
    // WebSocket 服务器端口号
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        // 对请求进行 WebSocket 升级
        conn, err := upgrader.Upgrade(w, r, nil)
        if err != nil {
            fmt.Println(err)
            return
        }

        // 将连接添加到 Channel
        connections <- conn
    })

    // 启动一个 Goroutine 处理 Channel 中的连接
    go handleConnections()

    http.ListenAndServe(":"+port, nil)
}

// handleConnections 处理 Channel 中的 WebSocket 连接
func handleConnections() {
    for {
        conn := <-connections

        wg.Add(1)
        go func() {
            defer wg.Done()
            for {
                msgType, msg, err := conn.ReadMessage()
                if err != nil {
                    fmt.Println(err)
                    break
                }

                if msgType == websocket.TextMessage {
                    // 处理文本消息
                    fmt.Println("Received text message:", string(msg))

                    // 向所有连接的客户端广播消息
                    for c := range connections {
                        if c != conn {
                            if err := c.WriteMessage(msgType, msg); err != nil {
                                fmt.Println(err)
                            }
                        }
                    }
                } else {
                    // 处理其他类型的消息
                }
            }

            conn.Close()
        }()
    }
}
登录后复制

通过管道传递连接可以在所有 Goroutine 之间共享连接,并避免创建过多线程带来的开销。

3. 第三方库

还有许多第三方库可以简化 WebSocket 并发处理,例如:

  • [gowebsocket](https://github.com/gobwas/ws)
  • [gorilla/websocket](https://github.com/gorilla/websocket)
  • [fasthttp/websocket](https://github.com/valyala/fasthttp/blob/master/websocket/websocket.go)

这些库提供了高级别的 API 来处理并发连接,并简化了 WebSocket 的使用。

以上是Go WebSocket 如何处理并发连接?的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
go
来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板