Maison > développement back-end > Golang > Comment utiliser le langage Go pour développer un système de transmission de données en temps réel basé sur Websocket

Comment utiliser le langage Go pour développer un système de transmission de données en temps réel basé sur Websocket

WBOY
Libérer: 2023-12-18 18:39:46
original
673 Les gens l'ont consulté

Comment utiliser le langage Go pour développer un système de transmission de données en temps réel basé sur Websocket

Comment utiliser le langage Go pour développer un système de transmission de données en temps réel basé sur Websocket, des exemples de code spécifiques sont nécessaires

Websocket est un protocole full-duplex, qui peut réaliser une transmission de données en temps réel sans actualiser la page. Dans les applications Web modernes, le transfert de données en temps réel constitue un élément crucial. Cet article expliquera comment utiliser le langage Go pour développer un système de transmission de données en temps réel basé sur Websocket, notamment comment implémenter du code côté serveur et côté client, et fournira des exemples de code spécifiques.

  1. Créer un serveur WebSocket

Pour créer un système de transmission de données en temps réel basé sur Websocket, vous devez d'abord créer un serveur Websocket. Dans Go, vous pouvez utiliser la bibliothèque gorilla/websocket pour créer un serveur Websocket.

Ce qui suit est un exemple de code pour un simple serveur 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)
}
Copier après la connexion

Dans cet exemple, nous définissons d'abord un programme de mise à niveau (upgrader), qui est utilisé pour mettre à niveau les connexions HTTP vers les connexions Websocket. Ensuite, nous définissons une fonction serveWs qui reçoit un rédacteur de réponse HTTP (w) et une requête HTTP (r) et met à niveau la connexion HTTP vers une connexion Websocket.

Dans la fonction serveWs, nous mettons d'abord à niveau la connexion HTTP vers une connexion Websocket. Nous utilisons ensuite une boucle pour lire les messages Websocket. Une fois que nous avons lu le message, nous le traitons et renvoyons le même message au client.

Enfin, dans la fonction main, on associe la fonction serveWs au chemin /ws et on démarre le serveur HTTP sur le port 8080.

  1. Créer un client Websocket

Avant de créer le client Websocket, nous devons créer une page HTML qui communiquera avec le serveur via Websocket. Voici un exemple de code pour une page HTML de base :

<!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>
Copier après la connexion

Dans cet exemple, nous créons une zone de texte (message) et un bouton (envoyer). Lorsque l'utilisateur clique sur le bouton d'envoi, nous envoyons le texte saisi au serveur via Websocket.

En JavaScript, nous utilisons l'objet WebSocket pour créer un client Websocket. Dans notre exemple, le client Websocket se connectera au chemin /ws et lorsqu'il recevra des messages du serveur, il les affichera sur la console.

  1. Exécutez le serveur et le client Websocket

Pour exécuter le serveur et le client Websocket, suivez ces étapes :

  1. Dans un terminal, utilisez la ligne de commande pour accéder au répertoire contenant l'exemple de code de serveur.
  2. Entrez la commande suivante pour démarrer le serveur :
go run main.go
Copier après la connexion
  1. Dans votre navigateur, ouvrez l'URL suivante pour charger l'exemple de page HTML :
http://localhost:8080/
Copier après la connexion
  1. Entrez du texte dans la zone de texte et cliquez sur le bouton Envoyer. Vous devriez voir les messages envoyés et renvoyés par le serveur, ainsi que leur sortie dans la console du navigateur.
  2. Transmission de données en temps réel

Maintenant, nous avons réussi à créer un serveur et un client Websocket simples, mais ce n'est que le début. Pour réaliser une transmission de données en temps réel, nous devons modifier le code côté serveur et côté client et utiliser goroutine côté serveur pour gérer plusieurs connexions Websocket.

Ce qui suit est un exemple de code qui implémente la transmission de données en temps réel :

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)
    }
}
Copier après la connexion

Dans cet exemple, nous définissons un Hub qui gère plusieurs clients Websocket. Chaque client dispose d'une goroutine de lecture (réception) et d'une goroutine d'écriture (envoi), qui gèrent respectivement les messages lus par le client et les messages envoyés au client.

En plus de traiter les messages des clients, Hub contient également un canal de diffusion pour diffuser des messages à tous les clients. Dans notre exemple, le Hub diffuse périodiquement la date et l'heure actuelles.

  1. Conclusion

Grâce aux exemples de code de cet article, nous avons appris à utiliser le langage Go pour créer un système de transmission de données en temps réel basé sur Websocket. Nous avons appris à utiliser la bibliothèque gorilla/websocket pour créer un serveur et un client Websocket, et implémenté comment gérer les entrées du client, comment envoyer des messages au client, et implémenté un Hub qui gère plusieurs clients Websocket, et implémenté la logique de diffuser des messages.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal