0

0

如何在Golang中处理WebSocket连接_Golang gorilla WebSocket包实践

P粉602998670

P粉602998670

发布时间:2026-01-20 11:22:03

|

777人浏览过

|

来源于php中文网

原创

gorilla/websocket.Upgrader.Upgrade() 返回 http.ErrUpgradeRequired 是因客户端未发送正确的升级请求头,必须包含 Upgrade: websocket 和 Connection: Upgrade。

如何在golang中处理websocket连接_golang gorilla websocket包实践

为什么 gorilla/websocketUpgrader.Upgrade() 会返回 http.ErrUpgradeRequired

这个错误不是连接失败,而是你没发对 HTTP 请求头。WebSocket 握手本质是 HTTP 协议升级,客户端必须带 Upgrade: websocketConnection: Upgrade,否则 Upgrade() 直接拒绝并返回该错误。

  • 检查前端是否用 new WebSocket("ws://...") 而非普通 fetchXMLHttpRequest
  • 若用 curl 测试,需手动加头:
    curl -i -N \
      -H "Connection: Upgrade" \
      -H "Upgrade: websocket" \
      -H "Sec-WebSocket-Version: 13" \
      -H "Sec-WebSocket-Key: $(openssl rand -base64 16)" \
      http://localhost:8080/ws
  • Nginx 反向代理时,必须显式透传升级头:
    location /ws {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

如何安全地并发读写 *websocket.Conn

gorilla/websocket 的连接对象**不支持并发读或并发写**,但允许一个 goroutine 读、另一个写——这是设计前提。直接多个 goroutine 调用 conn.WriteMessage() 会 panic:「concurrent write to websocket connection」。

  • 写操作必须串行:用 conn.SetWriteDeadline() 防僵死,再通过 channel 把消息统一交给一个「writer goroutine」处理
  • 读操作建议单 goroutine + conn.SetReadDeadline(),收到消息后投递到业务逻辑 channel(如 chan Message
  • 不要在 ReadMessage() 循环里直接调用耗时函数(比如 DB 查询),容易阻塞整个连接读取

conn.ReadMessage() 返回 websocket.CloseMessage 时该怎么做

这不是错误,是对方主动关闭连接的信号。此时你不该再调用 WriteMessage(),否则会报 use of closed network connection

Frase
Frase

Frase是一款出色的长篇 AI 写作工具,快速创建seo优化的内容。

下载
  • 检测到 messageType == websocket.CloseMessage 后,应立即跳出读循环,并调用 conn.Close()
  • 如果需要响应关闭帧,先调用 conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")),再关连接
  • 注意:conn.Close() 内部会发一次 CloseMessage,所以通常只需自己发一次响应帧,避免重复关闭

如何给每个 WebSocket 连接绑定用户身份并管理生命周期

别把用户 ID 存在全局 map 里裸用,容易竞态和泄漏。推荐用 sync.Map + 显式清理:

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

  • 连接建立后,从 JWT token 或 query 参数解析 user_id,存入 conn 的自定义字段(例如用 context.WithValue() 包裹 http.HandlerFunc
  • sync.Mapmap[string]*websocket.Conn,key 是 user_id;但注意:连接断开时必须显式 Delete(),不能只靠 GC
  • defer conn.Close() 前加清理逻辑:
    defer func() {
        if userID != "" {
            clients.Delete(userID)
        }
    }()
  • 心跳超时(如 30 秒无 PING)也得触发清理,否则僵尸连接堆积
实际跑起来最常卡住的地方,是忘记设读写 deadline,或者在 handler 里漏掉 defer conn.Close()。这两个点一旦出问题,连接不会立刻断,但内存和 goroutine 会缓慢上涨。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

179

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

228

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

209

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

392

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

197

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

191

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

192

2025.06.17

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

0

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 8.9万人学习

CSS3 教程
CSS3 教程

共18课时 | 4.7万人学习

Vue 教程
Vue 教程

共42课时 | 6.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号