如何在Golang中实现实时聊天功能_结合Websocket推送消息

7次阅读

Golang 实现实时聊天需用 WebSocket 替代 HTTP 轮询,核心是连接管理、消息分发和并发安全;通过 gorilla/websocket 升级连接,Hub 中心化管理客户端、广播消息,readPump/writePump 双 goroutine 解耦收发,前端用 ws 协议连接并处理收发与重连。

如何在 Golang 中实现实时聊天功能_结合 Websocket 推送消息

用 Golang 实现实时聊天功能,核心是用 WebSocket 替代 HTTP 轮询,让服务端能主动推消息给 前端。关键不在写多少代码,而在理清连接管理、消息分发和并发安全这三块。

gorilla/websocket 升级 HTTP 连接

WebSocket 不是新协议,而是通过 HTTP“握手”升级来的。Golang 原生不支持,得靠第三方库:

  • 执行 go get github.com/gorilla/websocket 安装依赖
  • 定义 Upgrader 并放开 跨域(开发可设CheckOrigin: func(r *http.Request) bool {return true},上线必须限制)
  • 在 HTTP路由 里调用 upgrader.Upgrade(w, r, nil),成功就拿到*websocket.Conn 实例
  • 每个连接建议立刻启动两个 goroutine:一个 readPump 收消息,一个 writePump 发消息,避免阻塞

设计中心化 Hub 管理所有连接

没有统一管理者,广播就无从谈起。Hub 不是可选模块,而是必建结构:

  • 定义type Hub struct {clients map[*Client]bool; broadcast chan []byte; register, unregister chan *Client}
  • clients存活跃连接,用指针作 key 更稳妥;broadcast 字节 流通道,所有要群发的消息都往里塞
  • register/unregister是控制通道,Hub 主循环用 select 监听它们,保证增删 map 的操作串行,避开并发读写 panic
  • 启动 hub.Run() 作为后台 goroutine,它不退出,一直协调消息流转

客户端收发与消息广播逻辑

每个 Client 对象封装连接和发送通道,消息流是单向解耦的:

立即学习go 语言免费学习笔记(深入)”;

  • 用户发消息 → readPump解析 JSON(含 username、message、time)→ 写入hub.broadcast
  • hub.Run()broadcast 取到消息 → 遍历 clients → 对每个 Client 的send 通道发一份
  • writePump监听自己 Client 的 send 通道 → 调用 conn.WriteMessage() 推给 浏览器
  • 断开连接时,先关 send 通道,再从 clients 删除,最后conn.Close()

前端配合要点

后端 再稳,前端连不上也白搭:

  • new WebSocket("ws://localhost:8080/ws") 建立连接,注意协议是 wswss,不是http
  • 监听 onmessage 接收 JSON 字符串,JSON.parse()后更新 DOM
  • 发送时构造{username: "A", message: "hello"},再ws.send(JSON.stringify(……))
  • onerroronclose处理异常断线,必要时自动重连
text=ZqhQzanResources