Golang WebSocket多客户端管理示例

答案:使用Golang和gorilla/websocket实现WebSocket多客户端管理,通过Client结构体封装连接,ClientManager进行注册、注销和广播。1. 客户端连接由Client结构体表示,包含Conn和Send通道;2. ClientManager维护客户端集合,处理注册、注销及消息广播;3. ServeHTTP升级HTTP连接并启动读写协程;4. readPump从客户端读取消息,writePump发送消息;5. Run方法监听事件并更新客户端状态。

golang websocket多客户端管理示例

在使用 Golang 构建 WebSocket 服务时,管理多个客户端连接是一个常见需求。下面是一个简洁、实用的多客户端管理示例,使用标准库 net/httpgorilla/websocket 实现。

依赖安装

go get github.com/gorilla/websocket

这是目前最常用的 WebSocket 第三方库。

WebSocket 客户端结构体设计

每个客户端连接封装为一个结构体,便于统一管理。

package mainimport (    "net/http"    "sync"    "github.com/gorilla/websocket")var upgrader = websocket.Upgrader{    CheckOrigin: func(r *http.Request) bool {        return true // 允许跨域,生产环境建议严格校验    },}type Client struct {    Conn *websocket.Conn    Send chan []byte}type ClientManager struct {    clients    map[*Client]bool    register   chan *Client    unregister chan *Client    broadcast  chan []byte    mutex      sync.RWMutex}

Client 表示一个 WebSocket 连接,包含连接实例和发送消息的通道。
ClientManager 是核心管理器,用于注册、注销和广播消息。

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

启动管理器并处理连接

实现管理器的运行逻辑和 HTTP 处理函数。

func NewClientManager() *ClientManager {    return &ClientManager{        clients:    make(map[*Client]bool),        register:   make(chan *Client),        unregister: make(chan *Client),        broadcast:  make(chan []byte),    }}func (manager *ClientManager) Run() {    for {        select {        case client := <-manager.register:            manager.mutex.Lock()            manager.clients[client] = true            manager.mutex.Unlock()            println("客户端加入,当前总数:", len(manager.clients))        case client := <-manager.unregister:            manager.mutex.Lock()            if _, ok := manager.clients[client]; ok {                delete(manager.clients, client)                close(client.Send)            }            manager.mutex.Unlock()            println("客户端退出,剩余:", len(manager.clients))        case message := <-manager.broadcast:            manager.mutex.RLock()            for client := range manager.clients {                select {                case client.Send <- message:                default:                    // 发送失败,关闭该连接                    manager.unregister <- client                }            }            manager.mutex.RUnlock()        }    }}func (manager *ClientManager) ServeHTTP(w http.ResponseWriter, r *http.Request) {    conn, err := upgrader.Upgrade(w, r, nil)    if err != nil {        http.Error(w, "WebSocket 升级失败", http.StatusBadRequest)        return    }    client := &Client{Conn: conn, Send: make(chan []byte, 10)}    manager.register <- client    go manager.readPump(client)    go manager.writePump(client)}

readPump 负责从客户端读取消息:

“`gofunc (manager *ClientManager) readPump(client *Client) { defer func() { manager.unregister }

writePump 负责向客户端发送消息:

```gofunc (manager *ClientManager) writePump(client *Client) { defer func() { manager.unregister <- client client.Conn.Close() }() for message := range client.Send { err := client.Conn.WriteMessage(websocket.TextMessage, message) if err != nil { break } }}

主函数启动服务

完整启动一个 WebSocket 服务,监听 8080 端口。

func main() {    manager := NewClientManager()    go manager.Run()    http.Handle("/ws", manager)    println("WebSocket 服务启动在 :8080/ws")    http.ListenAndServe(":8080", nil)}

访问 ws://localhost:8080/ws 的客户端将被纳入管理,任意客户端发送消息,其他所有客户端都能收到。

基本上就这些。这个示例结构清晰,易于扩展,比如加入用户ID、分组广播、心跳检测等。不复杂但容易忽略的是并发安全和连接异常处理,这里通过互斥锁和 defer 已做基础保障。

以上就是Golang WebSocket多客户端管理示例的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1412645.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月16日 06:31:16
下一篇 2025年12月16日 06:31:26

相关推荐

  • Golang如何使用go mod edit修改模块信息_Golang模块信息编辑操作详解

    go mod edit用于直接操作go.mod文件,支持修改模块路径、管理依赖和替换规则。使用-module可更改模块名称,-require和-droprequire添加或删除依赖,-replace实现模块重定向,-print预览修改,-fmt格式化文件,适合自动化场景。 在 Go 语言中,go m…

    2025年12月16日
    000
  • Go 程序性能分析:使用 pprof 进行 CPU 和内存剖析

    本教程旨在提供 go 语言 `pprof` 工具的简明使用指南,帮助开发者对 go 程序的 cpu 和内存性能进行剖析。通过结合 `go test` 命令生成性能数据文件,并利用 `go tool pprof` 分析这些文件,您可以有效地定位代码中的性能热点和内存泄漏,从而优化应用程序的执行效率。 …

    2025年12月16日
    000
  • Golang如何优化JSON序列化与反序列化

    使用结构体替代map可减少反射开销,通过json标签控制字段行为,结合高性能库如json-iterator/go提升序列化性能,避免大对象频繁处理并复用内存以优化吞吐量。 Go语言中JSON序列化与反序列化是Web服务和数据存储中的高频操作,性能优化直接影响系统吞吐量。关键在于减少反射开销、控制字段…

    2025年12月16日
    000
  • Go语言自定义字节切片复制函数:调试与实现

    本文探讨在go语言中,当内置copy函数引发unexpected fault address错误时,如何实现一个纯go语言的自定义字节切片复制函数。通过手动迭代方式,该实现旨在帮助开发者诊断程序逻辑或内存访问问题,作为调试工具而非性能替代品,确保数据复制的正确性。 诊断内置 copy 函数异常 在G…

    2025年12月16日
    000
  • 使用Go语言为整数添加千位分隔符:避免Perl式零宽断言的替代方案

    本文探讨了在go语言中为整数添加千位分隔符的挑战,特别是go标准库`regexp`对perl风格零宽断言支持的局限性。针对此问题,文章提出并详细讲解了一种基于字符串操作的替代算法,通过go代码示例展示了如何高效、可靠地实现数字格式化,避免了复杂正则匹配,提供了一种实用的解决方案。 在软件开发中,将大…

    2025年12月16日
    000
  • 如何在Golang中减少重复计算

    使用记忆化缓存函数结果,通过map和sync.Mutex避免重复计算;2. 提前计算并复用公共数据,如初始化阶段构建查找表;3. 利用sync.Once确保全局初始化仅执行一次;4. 将循环中不变的计算移出外部以减少开销。 在Golang中减少重复计算的核心思路是避免对相同输入反复执行耗时操作。通过…

    2025年12月16日
    000
  • Golang如何实现模块依赖自动化更新_Golang模块依赖自动更新操作详解

    Go语言通过Go Modules实现依赖自动更新,提升开发效率与安全性。首先使用go mod init初始化项目并生成go.mod文件,GO111MODULE=on启用模块支持;接着运行go list -m all查看当前依赖,go list -u -m all检测可升级版本;根据需要执行go ge…

    2025年12月16日
    000
  • Go语言实现文件系统树形结构:数据结构设计与实践

    本文探讨了如何使用go语言构建一个模拟文件系统的树形数据结构。通过定义file和folder两个结构体,并利用folder结构体内部嵌套自身切片的方式,实现了文件和文件夹的递归层级关系。文章提供了详细的代码示例,展示了如何创建、组织和打印一个具有多层嵌套的文件系统结构,为go语言初学者提供了清晰的实…

    2025年12月16日
    000
  • 如何在Golang中理解变量声明与初始化_Golang变量声明与初始化详解方法汇总

    变量声明使用var指定类型,初始化可自动推导类型,短变量声明:=仅限函数内使用,全局变量用var声明,未初始化变量有默认零值,支持批量分组声明。 在Golang中,变量的声明与初始化是编程的基础环节。理解它们的区别和使用场景,能帮助你写出更清晰、高效的代码。Go语言提供了多种方式来定义变量,每种方式…

    2025年12月16日
    000
  • 如何在Golang中实现云原生应用安全策略_Golang云原生应用安全策略方法汇总

    安全编码需验证输入并防注入,2. 用JWT和RBAC实现认证与访问控制,3. 强制HTTPS与mTLS保护通信,4. 通过环境变量与Secret管理敏感信息,5. 使用结构化日志与监控实现审计,6. 容器运行时最小权限与安全基线加固。 在Golang中构建云原生应用时,安全策略必须贯穿整个开发、部署…

    2025年12月16日
    000
  • Golang如何处理channel阻塞与死锁问题_Golang channel阻塞死锁解决技巧详解

    channel会阻塞因发送接收未同步:无缓冲需双方就绪,有缓冲在满或空时阻塞。1. 无缓冲channel发送阻塞若无接收方;2. 用goroutine分离发送接收可避免死锁;3. close(c)通知接收方结束等待;4. select配合default实现非阻塞通信;5. time.After用于超…

    2025年12月16日
    000
  • Golang如何实现任务并行处理

    Go语言通过goroutine和channel实现高效并发编程,核心是用goroutine执行任务、channel协调数据。02. 启动goroutine只需go关键字调用函数,但需注意main函数退出会终止所有协程。03. 使用sync.WaitGroup可可靠等待所有任务完成:启动前wg.Add…

    2025年12月16日
    000
  • 如何在Golang中实现文件拷贝

    使用io.Copy结合os.Open和os.Create是Go中推荐的文件拷贝方式,代码简洁且性能良好;可通过自定义缓冲区优化性能,并利用文件元信息保留源文件权限,确保数据安全写入磁盘。 在Golang中实现文件拷贝有多种方式,最常见的是使用标准库中的 io.Copy 函数结合 os.Open 和 …

    2025年12月16日
    000
  • 如何在Golang中使用switch语句

    Go的switch语句用于根据表达式值执行不同分支,比if-else更简洁。基本语法无需括号,匹配后自动终止;可省略表达式实现条件判断;支持多值case和fallthrough穿透;还可通过type断言判断接口类型,默认不穿透,需显式使用fallthrough。 在Golang中,switch语句是…

    2025年12月16日
    000
  • Golang如何通过reflect判断slice是否为空_Golang reflect slice空值判断实践

    答案:使用reflect判断slice是否为空需避免直接调用IsNil(),应通过Kind()确认类型后,结合IsValid()、IsZero()和Len()安全判断。示例中IsSliceEmpty函数正确处理nil和空slice,推荐用于Go 1.13+环境。 在Go语言中,使用 reflect …

    2025年12月16日
    000
  • 如何在Golang中实现待办事项管理项目

    在Golang中实现一个待办事项管理项目,核心是构建清晰的数据结构、提供基本的增删改查功能,并选择合适的存储方式。下面是一个简单但完整的实现思路,适合初学者上手并扩展。 定义待办事项结构体 每个待办事项通常包含ID、标题、是否完成和创建时间等字段。使用结构体来表示这些信息: type Todo st…

    2025年12月16日
    000
  • 如何在Golang中实现原型模式快速生成对象_Golang原型模式对象快速生成方法汇总

    答案:Golang中实现原型模式的核心是通过复制现有对象来创建新实例,常用方法包括结构体赋值(浅拷贝)、自定义Clone方法(深拷贝)、gob序列化(通用深拷贝)和原型管理器统一管理模板对象。 在Golang中实现原型模式的核心思路是通过已创建的对象作为“模板”,快速复制出新的实例,避免重复初始化带…

    2025年12月16日
    000
  • Golang如何解决环境变量配置问题_Golang环境变量配置及常见问题处理

    Go项目通过os包读取环境变量并结合godotenv库加载.env文件,推荐使用viper实现结构化配置管理,注意避免敏感信息泄露、正确处理类型转换及多环境配置区分。 Go语言项目在开发和部署过程中,经常需要读取环境变量来配置数据库连接、服务端口、密钥等敏感或差异化信息。合理管理环境变量不仅能提升安…

    2025年12月16日
    000
  • 如何在Golang中处理模块版本不一致_Golang模块版本一致性处理汇总

    使用go mod tidy、replace指令、清理缓存及vendor目录等方法可解决Go模块版本不一致问题,确保依赖统一。 在Go项目开发中,模块版本不一致是常见问题,可能导致构建失败、运行时错误或依赖冲突。Go Modules 从 Go 1.11 引入后,已成为官方依赖管理机制,但多人协作或长期…

    2025年12月16日
    000
  • 如何在Golang中修改嵌套结构体字段

    在Golang中修改嵌套结构体字段需确保变量可寻址、字段导出且指针非nil,通过点操作符或指针逐层访问即可修改。 在Golang中修改嵌套结构体字段的关键在于确保你操作的是可寻址的变量,而不是值的副本。只要结构体实例是可寻址的,就可以直接通过点操作符逐层访问并修改嵌套字段。 确保结构体是可寻址的 G…

    2025年12月16日
    000

发表回复

登录后才能评论
关注微信