【问题标题】:How to connect to a websocket using gorilla?如何使用 gorilla 连接到 websocket?
【发布时间】:2026-01-27 02:40:01
【问题描述】:

我想看一个关于如何使用 gorilla 连接到 websocket 的最小且简单的示例。

我发现连接到 websocket 的唯一示例是 this, 但我无法理解它,也找不到它如何工作的解释。

编辑:

第 20 行:
为什么他把websocket地址保存在flag.String而不是变量字符串?

第 26 行:
这部分是否会创建一个信号,在用户按下 crtl + C 时通知程序?

interrupt: = make(chan os.Signal, 1)
signal.Notify (interrupt, os.Interrupt)

第 32 行:
这条线有什么作用?

websocket.DefaultDialer.Dial (u.String (), nil)

第 60 行:
因为[]byte(t.String()) 而不是t.string()

【问题讨论】:

  • 如果您可以将您不理解的示例的确切部分添加到您的问题中,并询问有关它的具体问题,这将非常有帮助 - 例如。 “done 频道是做什么的?”等
  • 我对代码一无所知,但通过它的解释,我能够理解一个很好的部分,但是有一些疑问,我会更新问题
  • 我已经在下面的回答末尾回答了您的具体问题

标签: go websocket gorilla


【解决方案1】:

样本的README 说:

客户端每秒发送一条消息并打印收到的所有消息。

查看代码,后半部分(打印收到的所有消息)发生在这里:

go func() {
    defer close(done)
    for {
        _, message, err := c.ReadMessage()
        if err != nil {
            log.Println("read:", err)
            return
        }
        log.Printf("recv: %s", message)
    }
}()

这会启动一个 goroutine,它会循环读取来自 c(websocket 连接)的消息并将它们打印出来。它在读取失败时停止,这发生在错误和连接关闭时。

主 goroutine 这样做:

ticker := time.NewTicker(time.Second)
defer ticker.Stop()

for {
    select {
    case <-done:
        return
    case t := <-ticker.C:
        err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
        if err != nil {
            log.Println("write:", err)
            return
        }
    case <-interrupt:
        log.Println("interrupt")

        // Cleanly close the connection by sending a close message and then
        // waiting (with timeout) for the server to close the connection.
        err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
        if err != nil {
            log.Println("write close:", err)
            return
        }
        select {
        case <-done:
        case <-time.After(time.Second):
        }
        return
    }
}

它有一个每秒触发一次的ticker,消息被发送到websocket。当阅读器 goroutine 完成后,它会关闭 done 通道,该通道会使用 select 向这个循环发出信号以退出。

最后,有一个“中断”选择来处理 Ctrl+C,完全停止客户端。


回答您的具体问题:

第 20 行:此标志使您可以在执行程序时从命令行设置地址,而不是硬编码。例如,您可以像 client -addr localhost:9044 一样调用它来设置不同的端口。另见https://gobyexample.com/command-line-flags

第 26 行:是的,这是给 Ctrl+C 的;另见https://gobyexample.com/signals

第 32 行:DefaultDialerwebsocket 包中的 preconfigured 拨号器。根据文档,它相当于

var DefaultDialer = &Dialer{
    Proxy:            http.ProxyFromEnvironment,
    HandshakeTimeout: 45 * time.Second,
}

第 60 行:WriteMessage 采用 []byte,因此您必须将字符串转换为 []byte

【讨论】: