Maison  >  Article  >  développement back-end  >  Prise Web Golang

Prise Web Golang

WBOY
WBOYavant
2024-02-05 21:18:031031parcourir

Golang websocket

Contenu de la question

Quelqu'un peut-il m'aider à expliquer la signification de l'extrait de code suivant ?

var partner = make(chan io.ReadWriteCloser)

func match(c io.ReadWriteCloser) {
    fmt.Fprintln(c, "Waiting for a partner...")
    select {
    case partner <- c:
        // handled by the other goroutine
    case p := <-partner:
        chat(p, c)
    }
}

Version complète :

package main

import (
    "fmt"
    "golang.org/x/net/websocket"
    "html/template"
    "io"
    "log"
    "net/http"
)

const listenAddr = "localhost:4000"

type socket struct {
    conn *websocket.Conn
    done chan bool
}

func (s socket) Read(b []byte) (int, error) {
    return s.conn.Read(b)
}

func (s socket) Write(b []byte) (int, error) {
    return s.conn.Write(b)
}

func (s socket) Close() error {
    s.done <- true
    return nil
}

var rootTemplate = template.Must(template.New("root").Parse(`


    
        Websocket Chat - Golang
        
        <script>
            var input, output, websocket;

            function showMessage(msg) {
                var p = document.createElement("p");
                p.innerHTML = msg;
                output.appendChild(p);
            }
        
            function onMessage(e) {
                showMessage(e.data);
            }
            
            function onClose() {
                showMessage("Connection closed.");
            }
            
            function onKeyUp(e) {
                if (e.keyCode === 13) {
                    sendMessage();
                }
            }
            
            function sendMessage() {
                var msg = input.value;
                input.value = "";
                websocket.send(msg + "\n");
                showMessage(msg);
            }
            
            function init() {
                input = document.getElementById("input");
                input.addEventListener("keyup", onKeyUp, false);
                output = document.getElementById("output");
                websocket = new WebSocket("ws://{{.}}/socket");
                websocket.onmessage = onMessage;
                websocket.onclose = onClose;
            }
            
            window.addEventListener("load", init);
        </script>
    
    
        Say: 
        
`)) func rootHandler(w http.ResponseWriter, r *http.Request) { rootTemplate.Execute(w, listenAddr) } func socketHandler(conn *websocket.Conn) { s := socket{conn: conn, done: make(chan bool)} go match(s) <-s.done } var partner = make(chan io.ReadWriteCloser) func match(c io.ReadWriteCloser) { fmt.Fprintln(c, "Waiting for a partner...") select { case partner <- c: // handled by the other goroutine case p := <-partner: chat(p, c) } } func chat(a, b io.ReadWriteCloser) { fmt.Fprintln(a, "Found one! Say hi.") fmt.Fprintln(b, "Found one! Say hi.") errc := make(chan error, 1) go cp(a, b, errc) go cp(b, a, errc) if err := <-errc; err != nil { log.Println(err) } a.Close() b.Close() go io.Copy(b, a) io.Copy(a, b) } func cp(w io.Writer, r io.Reader, errc chan<- error) { _, err := io.Copy(w, r) errc <- err } func main() { http.HandleFunc("/", rootHandler) http.Handle("/socket", websocket.Handler(socketHandler)) err := http.ListenAndServe(listenAddr, nil) if err != nil { log.Fatal(err) } }

Je ne comprends pas très bien pourquoi cette fonction de chat peut être exécutée lorsque le deuxième participant rejoint le canal de chat.


Bonne réponse


Il semble que le gestionnaire HTTP ait créé un socket Web et ait commencé à attendre que l'autre partie se connecte. En effet, lors du traitement des requêtes HTTP, le gestionnaire appelle le canal match,这将在select上阻塞,因为partner qui n'est ni lisible ni inscriptible. Il n'y a pas de goroutines qui l'écoutent ou lui envoient.

Lorsque la deuxième demande arrive, match 会再次从另一个 goroutine 中调用。现在有两个 goroutine,并且它们可以匹配。其中一个 goroutine 可以发送到 partner chaîne, une autre goroutine la reçoit. L'objet du transfert est le lecteur et l'écrivain, qui sert ensuite à la communication entre les deux partenaires.

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer