如何使用Golang实现WebSocket客户端_连接服务器并收发消息

Golang WebSocket客户端核心是用gorilla/websocket.Dialer拨号并操作*websocket.Conn读写消息,支持超时、TLS、心跳及异常处理,适用于CLI工具与微服务通信。

用 Golang 实现 WebSocket 客户端,核心是使用 gorilla/websocket 库中的 websocket.Dialer 拨号连接服务端,并通过 *websocket.Conn 对象读写消息。它比浏览器 JS 客户端更可控,适合命令行工具、微服务间通信或后台长连接场景。

安装依赖与基础连接

确保已引入官方推荐库:

go get github.com/gorilla/websocket

创建客户端连接时需注意:

  • 使用 websocket.DefaultDialer 或自定义 Dialer(可设超时、TLS 配置等)
  • 连接地址格式为 ws://wss://,不能用 http://
  • 建议显式关闭连接,避免资源泄漏

发送与接收文本消息

连接成功后,可用 WriteMessageReadMessage 进行同步收发:

  • conn.WriteMessage(websocket.TextMessage, []byte("hello")) 发送 UTF-8 文本
  • msgType, data, err := conn.ReadMessage() 阻塞读取,返回消息类型和原始字节
  • 通常只处理 TextMessageBinaryMessage;控制帧(如 PingMessage)默认由底层自动响应

示例片段:

conn, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080/ws", nil)
if err != nil {
    log.Fatal(err)
}
defer conn.Close()

err = conn.WriteMessage(websocket.TextMessage, []byte("Hi from Go client"))
if err != nil {
    log.Fatal(err)
}

_, message, err := conn.ReadMessage()
if err != nil {
    log.Fatal(err)
}
log.Printf("收到: %s", message)

支持心跳与异常处理

生产环境需维持连接活跃并捕获断连:

  • 设置 Dialer.KeepAlive 或手动定时发 PingMessage
  • conn.SetPingHandler 可注册自定义 ping 响应逻辑(默认已内置)
  • conn.SetReadDeadline 防止 ReadMessage 长期阻塞
  • 网络错误(如 websocket.CloseError)应主动退出循环并关闭连接

完整可运行客户端示例

以下是一个带超时、简单交互的 CLI 客户端:

package main

import (
    "bufio"
    "log"
    "os"
    "time"
    "github.com/gorilla/websocket"
)

func main() {
    c, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080/ws", nil)
    if err != nil {
        log.Fatal("连接失败:", err)
    }
    defer c.Close()

    // 启动接收协程
    go func() {
        for {
            _, msg, err := c.ReadMessage()
            if err != nil {
                log.Println("接收失败:", err)
                return
            }
            log.Printf("← %s", msg)
        }
    }()

    // 主线程读取标准输入并发送
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        text := scanner.Text()
        if text == "quit" {
            break
        }
        err := c.WriteMessage(websocket.TextMessage, []byte(text))
        if err != nil {
            log.Println("发送失败:", err)
            break
        }
    }
}

运行后可在终端输入文字发送,服务端回显内容会实时打印在日志中。