Go Academy · 课时

使用 gorilla/websocket

升级并处理连接

第 2 / 4 课13 个步骤

使用 gorilla/websocket 是 CoddyKit 上的免费 Go Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Go Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Go Academy 课程共包含 4 节课。

gorilla/websocket 库

gorilla/websocket 是使用最广泛的 Go WebSocket 库。它负责处理升级握手,并提供连接对象来读写帧。请使用 go get github.com/gorilla/websocket 安装。

import "github.com/gorilla/websocket"

升级器

Upgrader 会将 HTTP 请求转换为 WebSocket 连接。您可以配置缓冲区大小和来源检查。

var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}

CheckOrigin 与安全性

默认情况下,Upgrader 会拒绝跨来源请求。在开发期间,您可以放宽这一限制,但在生产环境中请验证 Origin 标头,以防止跨站 WebSocket 劫持。

upgrader.CheckOrigin = func(r *http.Request) bool {
    return r.Header.Get("Origin") == "https://myapp.com"
}

在处理函数中执行升级

在 http.HandlerFunc 内调用 Upgrade。成功后,您会得到一个 *websocket.Conn。

func wsHandler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        return
    }
    defer conn.Close()
    // read/write loop here
}

读取消息

ReadMessage 会一直阻塞,直到某个帧到达,然后返回消息类型和负载字节。

mt, data, err := conn.ReadMessage()
if err != nil {
    return // client closed or error
}
fmt.Printf("got %d bytes\n", len(data))
_ = mt

写入消息

WriteMessage 会发送指定类型的帧:

err := conn.WriteMessage(websocket.TextMessage, []byte("hello"))
if err != nil {
    return
}

回显循环

一个经典示例是读取消息,然后将其写回。Read 返回错误时循环结束(表示客户端已断开连接)。

for {
    mt, msg, err := conn.ReadMessage()
    if err != nil {
        break
    }
    conn.WriteMessage(mt, msg)
}

JSON 辅助函数

gorilla 提供 ReadJSON 和 WriteJSON,可以直接通过套接字编组和解组 Go 值,这对结构化消息很方便。在实际源代码中,Msg 结构体字段带有 json:"text" 标记。

type Msg struct {
    Text string // tag: json text
}
var m Msg
conn.ReadJSON(&m)
conn.WriteJSON(Msg{Text: "ack"})

一个读取器、一个写入器规则

请注意:单个连接同时只能有一个并发读取器和一个并发写入器。如果多个协程进行写入,请使用互斥锁,或让一个协程统一处理写入(广播部分会介绍这种做法)。

注册路由

像注册任何 HTTP 路由一样连接处理函数。客户端连接到 ws://host/ws。

http.HandleFunc("/ws", wsHandler)
http.ListenAndServe(":8080", nil)

可运行示例:JSON 往返类比

WebSocket 代码需要外部库;下面这段标准库代码通过将传入消息解组到映射中,再将回复编组,来模拟 ReadJSON/WriteJSON。

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    in := []byte("{\"text\":\"ping\"}")
    var m map[string]string
    json.Unmarshal(in, &m)
    reply, _ := json.Marshal(map[string]string{"text": m["text"] + "-ack"})
    fmt.Println(string(reply))
}

快速检查

请测试您对 gorilla/websocket 用法的理解。

回顾

您学会了使用 gorilla/websocket:

  • Upgrader 执行握手;请验证 CheckOrigin
  • Upgrade 返回一个 *websocket.Conn
  • 使用 ReadMessage/WriteMessage 或 JSON 辅助函数
  • 每个连接同时只能有一个读取器和一个写入器
免费开始

用 AI 导师学习 Go — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
51
课程
203

常见问题解答

「使用 gorilla/websocket」课时是免费的吗?

是的 — 「使用 gorilla/websocket」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。

「使用 gorilla/websocket」这节课中我会学到什么?

升级并处理连接 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Go Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「使用 gorilla/websocket」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Go Academy 课中编写并运行代码吗?

能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. WebSocket 基础
  2. 使用 gorilla/websocket
  3. 广播消息
  4. 连接管理
← 返回 Go Academy