Golang websocket

WBOY
Lepaskan: 2024-02-05 21:18:03
ke hadapan
1119 orang telah melayarinya

Golang websocket

Kandungan soalan

Bolehkah sesiapa membantu menerangkan maksud coretan kod berikut?

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)
    }
}
Salin selepas log masuk

Versi penuh:

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) } }
Salin selepas log masuk

Saya tidak begitu faham mengapa fungsi sembang ini boleh dilaksanakan apabila peserta kedua menyertai saluran sembang.


Jawapan betul


Nampaknya pengendali HTTP mencipta soket web dan mula menunggu pihak lain menyambung. Ini kerana apabila mengendalikan permintaan HTTP, pengendali memanggil saluran match,这将在select上阻塞,因为partner yang tidak boleh dibaca dan tidak boleh ditulis. Tidak ada goroutine yang mendengarnya, atau menghantarnya.

Apabila permintaan kedua datang, match 会再次从另一个 goroutine 中调用。现在有两个 goroutine,并且它们可以匹配。其中一个 goroutine 可以发送到 partner saluran, goroutine lain menerimanya. Objek pemindahan adalah pembaca dan penulis, yang kemudiannya digunakan untuk komunikasi antara dua rakan kongsi.

Atas ialah kandungan terperinci Golang websocket. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan