>백엔드 개발 >Golang >Go 언어를 사용하여 Websocket 기반 실시간 데이터 전송 시스템을 개발하는 방법

Go 언어를 사용하여 Websocket 기반 실시간 데이터 전송 시스템을 개발하는 방법

WBOY
WBOY원래의
2023-12-18 18:39:46695검색

Go 언어를 사용하여 Websocket 기반 실시간 데이터 전송 시스템을 개발하는 방법

Go 언어를 사용하여 Websocket 기반의 실시간 데이터 전송 시스템을 개발하는 방법에는 구체적인 코드 예제가 필요합니다.

Websocket은 페이지를 새로 고치지 않고도 실시간 데이터 전송이 가능한 전이중 프로토콜입니다. 최신 웹 애플리케이션에서는 실시간 데이터 전송이 중요한 부분입니다. 이 글에서는 Go 언어를 사용하여 Websocket 기반의 실시간 데이터 전송 시스템을 개발하는 방법을 소개하고, 서버 측 코드와 클라이언트 측 코드를 구현하는 방법을 소개하고, 구체적인 코드 예제를 제공합니다.

  1. WebSocket 서버 만들기

Websocket 기반의 실시간 데이터 전송 시스템을 만들려면 먼저 Websocket 서버를 만들어야 합니다. Go에서는 gorilla/websocket 라이브러리를 사용하여 Websocket 서버를 생성할 수 있습니다.

다음은 간단한 Websocket 서버의 샘플 코드입니다.

package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/websocket"
)

// 定义升级器
var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}

func serveWs(w http.ResponseWriter, r *http.Request) {
    // 升级请求为Websocket
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println(err)
        return
    }

    // 读取Websocket消息
    for {
        messageType, p, err := conn.ReadMessage()
        if err != nil {
            fmt.Println(err)
            return
        }

        // 处理消息
        fmt.Println(string(p))

        // 回复消息
        err = conn.WriteMessage(messageType, p)
        if err != nil {
            fmt.Println(err)
            return
        }
    }
}

func main() {
    http.HandleFunc("/ws", serveWs)
    http.ListenAndServe(":8080", nil)
}

이 예에서는 먼저 HTTP 연결을 Websocket 연결로 업그레이드하는 데 사용되는 업그레이드 프로그램(upgrader)을 정의합니다. 그런 다음 HTTP 응답 작성자(w)와 HTTP 요청(r)을 수신하고 HTTP 연결을 웹소켓 연결로 업그레이드하는 함수serveWs를 정의합니다.

serveWs 기능에서는 먼저 HTTP 연결을 Websocket 연결로 업그레이드합니다. 그런 다음 루프를 사용하여 Websocket 메시지를 읽습니다. 메시지를 읽은 후에는 이를 처리하고 동일한 메시지를 클라이언트에 다시 보냅니다.

마지막으로 메인 함수에서 ServeWs 함수를 /ws 경로와 연결하고 포트 8080에서 HTTP 서버를 시작합니다.

  1. Websocket 클라이언트 만들기

Websocket 클라이언트를 만들기 전에 Websocket을 통해 서버와 통신할 HTML 페이지를 만들어야 합니다. 다음은 기본 HTML 페이지의 샘플 코드입니다.

<!DOCTYPE html>
<html>
<head>
    <title>Websocket Example</title>
</head>
<body>

    <textarea id="message"></textarea>
    <button onclick="send()">Send</button>

    <script>
    // 创建Websocket对象
    var ws = new WebSocket("ws://localhost:8080/ws");

    // 接收来自服务器的消息
    ws.onmessage = function(event) {
        console.log(event.data);
    };

    // 发送消息到服务器
    function send() {
        var input = document.getElementById("message");
        ws.send(input.value);
        input.value = "";
    }
    </script>

</body>
</html>

이 예에서는 텍스트 영역(메시지)과 버튼(보내기)을 만듭니다. 사용자가 보내기 버튼을 클릭하면 입력된 텍스트가 Websocket을 통해 서버로 전송됩니다.

JavaScript에서는 WebSocket 개체를 사용하여 Websocket 클라이언트를 만듭니다. 이 예에서 Websocket 클라이언트는 /ws 경로에 연결하고 서버로부터 메시지를 받으면 해당 메시지를 콘솔에 출력합니다.

  1. Websocket 서버 및 클라이언트 실행

Websocket 서버 및 클라이언트를 실행하려면 다음 단계를 따르세요.

  1. 터미널에서 명령줄을 사용하여 샘플 서버 코드가 포함된 디렉터리로 변경합니다.
  2. 다음 명령을 입력하여 서버를 시작하세요.
go run main.go
  1. 브라우저에서 다음 URL을 열어 샘플 HTML 페이지를 로드하세요.
http://localhost:8080/
  1. 텍스트 영역에 텍스트를 입력하고 보내기 버튼을 클릭하세요. 서버로 전송 및 반환되는 메시지와 브라우저 콘솔에 출력되는 메시지를 볼 수 있습니다.
  2. 실시간 데이터 전송

이제 간단한 Websocket 서버와 클라이언트를 성공적으로 생성했지만 이는 시작에 불과합니다. 실시간 데이터 전송을 달성하려면 서버 측 및 클라이언트 측 코드를 수정하고 서버 측에서 goroutine을 사용하여 여러 Websocket 연결을 처리해야 합니다.

다음은 실시간 데이터 전송을 구현하는 샘플 코드입니다.

package main

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

    "github.com/gorilla/websocket"
)

// 定义升级器
var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}

// 定义客户端
type Client struct {
    conn *websocket.Conn
    send chan []byte
}

// 处理客户端消息
func (c *Client) read() {
    defer func() {
        c.conn.Close()
    }()
    for {
        messageType, p, err := c.conn.ReadMessage()
        if err != nil {
            fmt.Println(err)
            return
        }
        // 处理消息
        fmt.Printf("Received: %s
", p)
    }
}

// 发送消息到客户端
func (c *Client) write() {
    defer func() {
        c.conn.Close()
    }()
    for {
        select {
        case message, ok := <-c.send:
            if !ok {
                c.conn.WriteMessage(websocket.CloseMessage, []byte{})
                return
            }
            writer, err := c.conn.NextWriter(websocket.TextMessage)
            if err != nil {
                return
            }
            writer.Write(message)
            if err := writer.Close(); err != nil {
                return
            }
        }
    }
}

// 定义Hub
type Hub struct {
    clients map[*Client]bool
    broadcast chan []byte
    register chan *Client
    unregister chan *Client
}

// 创建Hub
func newHub() *Hub {
    return &Hub{
        clients:    make(map[*Client]bool),
        broadcast:  make(chan []byte),
        register:   make(chan *Client),
        unregister: make(chan *Client),
    }
}

// 运行Hub
func (h *Hub) run() {
    for {
        select {
        case client := <-h.register:
            h.clients[client] = true
            fmt.Println("Client registered")
        case client := <-h.unregister:
            if _, ok := h.clients[client]; ok {
                delete(h.clients, client)
                close(client.send)
                fmt.Println("Client unregistered")
            }
        case message := <-h.broadcast:
            for client := range h.clients {
                select {
                case client.send <- message:
                    fmt.Printf("Sent: %s
", message)
                default:
                    close(client.send)
                    delete(h.clients, client)
                }
            }
        }
    }
}

func serveWs(hub *Hub, w http.ResponseWriter, r *http.Request) {
    // 升级请求为Websocket
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println(err)
        return
    }

    // 创建客户端
    client := &Client{
        conn: conn,
        send: make(chan []byte),
    }

    // 注册客户端
    hub.register <- client

    // 读取Websocket消息
    go client.read()

    // 发送Websocket消息
    go client.write()
}

func main() {
    // 创建Hub
    hub := newHub()

    // 运行Hub
    go hub.run()

    // 定期广播消息
    go func() {
        for {
            hub.broadcast <- []byte(fmt.Sprintf("Server Time: %s", time.Now().Format("2006-01-02 15:04:05")))
            time.Sleep(1 * time.Second)
        }
    }()

    // 启动HTTP服务器
    http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
        serveWs(hub, w, r)
    })
    http.Handle("/", http.FileServer(http.Dir(".")))
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        panic(err)
    }
}

이 예에서는 여러 Websocket 클라이언트를 관리하는 허브를 정의합니다. 각 클라이언트에는 클라이언트에서 읽은 메시지와 클라이언트로 보낸 메시지를 각각 처리하는 읽기(수신) 고루틴과 쓰기(보내기) 고루틴이 있습니다.

허브에는 클라이언트 메시지 처리 외에도 모든 클라이언트에게 메시지를 방송하기 위한 방송 채널도 포함되어 있습니다. 이 예에서 허브는 현재 날짜와 시간을 주기적으로 브로드캐스트합니다.

  1. 결론

이 기사의 코드 예제를 통해 Go 언어를 사용하여 Websocket 기반의 실시간 데이터 전송 시스템을 만드는 방법을 배웠습니다. gorilla/websocket 라이브러리를 사용하여 Websocket 서버와 클라이언트를 생성하는 방법을 배웠고, 클라이언트의 입력을 처리하는 방법과 클라이언트에 메시지를 보내는 방법을 구현하고, 여러 Websocket 클라이언트를 관리하는 허브를 구현하고, 다음의 논리를 구현했습니다. 방송 메시지.

위 내용은 Go 언어를 사용하여 Websocket 기반 실시간 데이터 전송 시스템을 개발하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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