Go语言如何实现WebSocket通信_WebSocket基础用法
#技术教程 发布时间: 2026-01-13
Go标准库不支持WebSocket,需用gorilla/websocket;服务端用Upgrader升级连接后读写消息,客户端需手动拨号并处理重连与超时。
Go标准库不支持WebSocket,必须用第三方包
Go语言原生net/http包只提供HTTP协议支持,没有内置WebSocket实现。直接调用http.ResponseWriter的Write方法或试图升级连接会失败,因为缺少WebSocket握手、帧解析和心跳等关键逻辑。
主流选择是gorilla/websocket——它稳定、文档清晰、被大量生产项目验证。别用已归档的golang.org/x/net/websocket,也不建议从零手写WebSocket帧处理。
服务端:用gorilla/websocket建立连接并读写消息
核心是websocket.Upgrader升级HTTP请求,再用*websocket.Conn收发数据。注意升级过程必须在HTTP handler中完成,且不能有任何前置Write或Header修改(否则触发http: multiple response.WriteHeader calls错误)。
-
Upgrader.CheckOrigin默认拒绝跨域请求,开发时可临时设为func(r *http.Request) bool { return true },生产环境应校验Origin头 - 读取消息用
conn.ReadMessage(),返回(int, []byte, error),第一个值是消息类型(websocket.TextMessage或websocket.BinaryMessage) - 发送消息用
conn.WriteMessage(),第二个参数必须是[]byte;若传字符串,需先转[]byte("hello") - 连接应显式关闭:
conn.Close(),否则可能泄漏goroutine和文件描述符
package main
import (
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool { return true },
}
func wsHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Upgrade error:", err)
return
}
defer conn.Close()
for {
_, msg, err := conn.ReadMessage()
if err != nil {
log.Println("Read error:", err)
break
}
if err := conn.WriteMessage(websocket.TextMessage, msg); err != nil {
log.Println("Write error:", err)
break
}
}
}
func main() {
http.HandleFunc("/ws", wsHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
客户端:用websocket.Dial连接并处理断线重连
浏览器端用new WebSocket("ws://localhost:8080/ws")即可,但Go客户端需主动拨号。常见陷阱是忽略TLS配置(wss://需传&tls.Config{InsecureSkipVerify: true}仅限测试)、未设置读写超时导致goroutine卡死。
-
websocket.DefaultDialer默认无超时,务必设置TLSClientConfig和Proxy(如需代理) - 读写操作可能阻塞,建议用
conn.SetReadDeadline()和conn.SetWriteDeadline()控制超时 - 断线后不能复用旧
*websocket.Conn,必须重新Dial;重连逻辑需自己实现(例如指数退避) - 发送JSON数据时,先
json.Marshal再WriteMessage;接收时先ReadMessage再json.Unmarshal
消息粘包与并发安全:每个连接应独占一个goroutine
websocket.Conn本身不是并发安全的——多个goroutine同时调用WriteMessage会panic(concurrent write to websocket connection)。但ReadMessage可以并发调用,只要写操作被串行化。
- 典型模式:一个goroutine循环
ReadMessage,另一个goroutine负责WriteMessage,通过chan []byte通信 - 不要在HTTP handler里直接处理业务逻辑,应把
conn交给worker goroutine,并用defer conn.Close()确保清理 - 大消息(>1MB)可能触发
websocket: close sent,需调大Upgrader.ReadBufferSize和WriteBufferSize
真正难的是状态同步和连接生命周期管理,比如用户登录态如何绑定到Conn、如何广播消息给房间内所有人—
—这些不在WebSocket协议层,得自己设计。
上一篇 : 京东双十二百亿补贴怎么领 京东双十二红包雨每日整点抢
下一篇 : Java面试——MyBatis中#{}与${}的区别
-
SEO外包最佳选择国内专业的白帽SEO机构,熟知搜索算法,各行业企业站优化策略!
SEO公司
-
可定制SEO优化套餐基于整站优化与品牌搜索展现,定制个性化营销推广方案!
SEO套餐
-
SEO入门教程多年积累SEO实战案例,从新手到专家,从入门到精通,海量的SEO学习资料!
SEO教程
-
SEO项目资源高质量SEO项目资源,稀缺性外链,优质文案代写,老域名提权,云主机相关配置折扣!
SEO资源
-
SEO快速建站快速搭建符合搜索引擎友好的企业网站,协助备案,域名选择,服务器配置等相关服务!
SEO建站
-
快速搜索引擎优化建议没有任何SEO机构,可以承诺搜索引擎排名的具体位置,如果有,那么请您多注意!专业的SEO机构,一般情况下只能确保目标关键词进入到首页或者前几页,如果您有相关问题,欢迎咨询!