首页 > 后端开发 > Golang > 正文

Golang websocket

WBOY
发布: 2024-02-05 21:18:03
转载
1083 人浏览过

Golang websocket

问题内容

谁能帮忙解释一下下面的代码片段的含义吗?

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)
    }
}
登录后复制

完整版:

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) } }
登录后复制

不太明白为什么当第二个加入者加入聊天频道时可以执行这个聊天功能。


正确答案


看起来 HTTP 处理程序创建了一个 Web 套接字并开始等待另一方连接。这是因为当处理HTTP请求时,处理程序调用match,这将在select上阻塞,因为partner通道既不可读也不可写。没有 goroutine 监听它,或者发送给它。

当第二个请求到来时,match 会再次从另一个 goroutine 中调用。现在有两个 goroutine,并且它们可以匹配。其中一个 goroutine 可以发送到 partner 通道,另一个 goroutine 接收它。传输的对象是读写器,然后用于两个伙伴之间的通信。

以上是Golang websocket的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:stackoverflow.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板