>백엔드 개발 >Golang >Go WebSocket 서버를 설정하는 방법은 무엇입니까?

Go WebSocket 서버를 설정하는 방법은 무엇입니까?

WBOY
WBOY원래의
2024-05-31 22:47:59836검색

Go WebSocket 서버 구축 방법: gorilla/websocket 라이브러리를 설치합니다. WebSocket 핸드셰이크 요청을 처리할 HTTP 서버를 만듭니다. HTTP 요청을 WebSocket 연결로 업그레이드합니다. 데이터 전송 및 수신을 포함하여 서버 측에서 WebSocket 메시지를 처리합니다. 클라이언트가 특정 채널을 구독하고 해당 채널에서만 메시지를 받을 수 있도록 서버를 확장할 수 있습니다.

Go WebSocket 服务器如何搭建?

Go WebSocket 서버 구축

WebSocket은 클라이언트와 서버가 단일 TCP 연결을 통해 양방향으로 데이터를 전송할 수 있게 해주는 전이중 통신 프로토콜입니다. Go 언어는 WebSocket 서버 구축을 위한 강력한 지원을 제공합니다. 이 기사에서는 Go를 사용하여 WebSocket 서버를 만드는 방법을 실제 예제와 함께 소개합니다.

시작하기

먼저 Go 컴파일러와 코드 편집기가 포함된 Go 개발 환경이 필요합니다. Go에서 WebSocket 구현을 제공하는 gorilla/websocket 라이브러리도 설치해야 합니다. gorilla/websocket 库,它提供了 Go 语言的 WebSocket 实现。

go get -u github.com/gorilla/websocket

创建服务器

WebSocket 服务器本质上是一个传统的 HTTP 服务器,但它处理的是 WebSocket 握手请求。下面是如何在 Go 中创建 WebSocket 服务器:

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/gorilla/websocket"
)

func main() {
    // 升级 HTTP 请求到 WebSocket 连接
    upgrader := websocket.Upgrader{
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
    }

    http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
        conn, err := upgrader.Upgrade(w, r, nil)
        if err != nil {
            log.Fatal(err)
        }

        // websocket.Conn 是一个双向的连接
        for {
            // 从客户端接收消息
            messageType, p, err := conn.ReadMessage()
            if err != nil {
                log.Fatal(err)
            }

            // 将消息返回客户端
            if err := conn.WriteMessage(messageType, p); err != nil {
                log.Fatal(err)
            }
        }
    })

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

实战案例

现在,我们来扩展这个服务器,允许客户端订阅特定的频道并仅接收来自这些频道的消息。

package main

import (
    "fmt"
    "log"
    "net/http"
    "sync"

    "github.com/gorilla/websocket"
)

type channel struct {
    sync.Mutex
    clients map[*websocket.Conn]bool
}

var channels = struct {
    sync.RWMutex
    m map[string]*channel
}{m: make(map[string]*channel)}

func NewChannel(name string) *channel {
    channels.Lock()
    defer channels.Unlock()

    if _, ok := channels.m[name]; !ok {
        channels.m[name] = &channel{clients: make(map[*websocket.Conn]bool)}
    }
    return channels.m[name]
}

func main() {
    upgrader := websocket.Upgrader{
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
    }

    http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
        conn, err := upgrader.Upgrade(w, r, nil)
        if err != nil {
            log.Fatal(err)
        }

        // 订阅和取消订阅频道
        go func() {
            for {
                // 从客户端接收消息
                messageType, p, err := conn.ReadMessage()
                if err != nil {
                    log.Fatal(err)
                }

                // 如果消息是一种订阅请求,则将连接添加到相应频道
                if messageType == websocket.TextMessage && string(p)[:4] == "join" {
                    channelName := string(p)[5:]
                    channel := NewChannel(channelName)

                    // 锁定频道的客户端列表
                    channel.Lock()
                    channel.clients[conn] = true
                    // 解锁频道的客户端列表
                    channel.Unlock()
                }

                // 如果消息是一种取消订阅请求,则将连接从相应频道中移除
                if messageType == websocket.TextMessage && string(p)[:7] == "leave" {
                    channelName := string(p)[8:]
                    channel := NewChannel(channelName)

                    channel.Lock()
                    delete(channel.clients, conn)
                    channel.Unlock()
                }
            }
        }()

        // 广播消息到客户端
        go func() {
            for {
                // 分别广播来自每个频道的消息
                channels.RLock()
                for _, channel := range channels.m {
                    channel.RLock()
                    for client := range channel.clients {
                        if err := client.WriteMessage(websocket.TextMessage, "hello"); err != nil {
                            // 如果写入失败,则从频道中移除连接
                            channel.Lock()
                            delete(channel.clients, client)
                            channel.Unlock()
                        }
                    }
                    channel.RUnlock()
                }
                channels.RUnlock()
            }
        }()
    })

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

现在,你可以启动服务器并使用 WebSocket 客户端连接到 /wsrrreee

서버 만들기🎜🎜 WebSocket 서버는 기본적으로 기존 HTTP 서버이지만 WebSocket 핸드셰이크 요청을 처리합니다. Go에서 WebSocket 서버를 생성하는 방법은 다음과 같습니다. 🎜rrreee🎜 실제 예 🎜🎜 이제 클라이언트가 특정 채널을 구독하고 해당 채널에서만 메시지를 받을 수 있도록 이 서버를 확장해 보겠습니다. 🎜rrreee🎜이제 서버를 시작하고 WebSocket 클라이언트를 사용하여 /ws 엔드포인트에 연결하고, 채널을 구독하고, 채널에서 메시지를 받을 수 있습니다. 🎜

위 내용은 Go WebSocket 서버를 설정하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.