Maison  >  Article  >  développement back-end  >  Comment Go WebSocket fonctionne-t-il avec d’autres protocoles ?

Comment Go WebSocket fonctionne-t-il avec d’autres protocoles ?

WBOY
WBOYoriginal
2024-06-05 12:58:561103parcourir

Go WebSocket fonctionne avec d'autres protocoles, notamment : HTTP/HTTPS : WebSocket s'exécute généralement sur HTTP/HTTPS, le protocole WebSocket étant négocié via un processus de prise de contact. gRPC : gRPC est un framework RPC qui s'intègre à WebSocket pour effectuer des appels RPC à faible latence et à haut débit entre les clients et les serveurs.

Go WebSocket 如何与其他协议配合使用?

Comment Go WebSocket fonctionne avec d'autres protocoles

WebSocket est un protocole de communication full-duplex entre client et serveur. Il est couramment utilisé pour créer des applications en temps réel telles que le chat, la messagerie et les jeux. WebSocket peut être utilisé dans un large éventail de scénarios avec d'autres protocoles tels que HTTP, HTTPS, gRPC et WebSockets.

Utilisation de HTTP et HTTPS

Les WebSockets s'exécutent généralement au-dessus de HTTP ou HTTPS. Lorsqu'un client établit une connexion WebSocket au serveur, il envoie d'abord une requête HTTP contenant un en-tête spécial appelé "Upgrade" avec sa valeur définie sur "websocket". Le serveur répond à cette requête par un en-tête « Upgrade » dont la valeur est également définie sur « websocket ». Ce processus d'établissement de liaison permet au client et au serveur de négocier l'utilisation du protocole WebSocket et d'établir un canal de communication en duplex intégral sur HTTP/HTTPS.

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

    "github.com/gorilla/websocket"
)

const (
    port = ":8080"
)

var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}

func main() {
    http.HandleFunc("/", indexHandler)
    http.HandleFunc("/ws", websocketHandler)

    log.Printf("Listening on port %s", port)
    if err := http.ListenAndServe(port, nil); err != nil {
        log.Fatal(err)
    }
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Welcome to the WebSocket page.")
}

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    for {
        mt, message, err := conn.ReadMessage()
        if err != nil {
            log.Println(err)
            conn.Close()
            break
        }

        if err := conn.WriteMessage(mt, message); err != nil {
            log.Println(err)
            conn.Close()
            break
        }
    }
}

Utilisation de gRPC

gRPC est un framework d'appel de procédure à distance (RPC) hautes performances qui peut être utilisé avec WebSocket. Le client utilise les fonctions gRPC pour appeler les méthodes côté serveur, et la méthode côté serveur utilise WebSocket pour envoyer des réponses. Cette intégration permet aux applications de gérer les appels RPC avec une faible latence et un haut débit.

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

    "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
    "github.com/gorilla/websocket"
    "google.golang.org/protobuf/proto"
)

const (
    port  = ":8080"
    grpcAddr = ":50051"
)

var upgrader = websocket.Upgrader{}
var mux *runtime.ServeMux

func main() {
    mux = runtime.NewServeMux()

    grpcConn, err := grpc.DialContext(
        context.Background(),
        grpcAddr,
        grpc.WithInsecure(),
        )
    if err != nil {
        log.Fatal(err)
    }

    // 注册 gRPC 服务到网关。
    if err := helloworldpb.RegisterGreeterHandler(context.Background(), mux, grpcConn); err != nil {
        log.Fatal(err)
    }

    http.HandleFunc("/", indexHandler)
    http.HandleFunc("/grpc-ws", websocketHandler)

    log.Printf("Listening on port %s", port)
    if err := http.ListenAndServe(port, nil); err != nil {
        log.Fatal(err)
    }
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Welcome to the gRPC-WebSocket page.")
}

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    for {
        mt, message, err := conn.ReadMessage()
        if err != nil {
            log.Println(err)
            conn.Close()
            break
        }

        req := &helloworldpb.HelloRequest{}
        if err := proto.Unmarshal(message, req); err != nil {
            log.Println(err)
            conn.Close()
            break
        }

        ctx := context.Background()
        resp, err := helloworldpb.NewGreeterClient(grpcConn).SayHello(ctx, req)
        if err != nil {
            log.Println(err)
            conn.Close()
            break
        }

        message, err := proto.Marshal(resp)
        if err != nil {
            log.Println(err)
            conn.Close()
            break
        }

        if err := conn.WriteMessage(mt, message); err != nil {
            log.Println(err)
            conn.Close()
            break
        }
    }
}

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!

Déclaration:
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