当前位置: 首页 > backend >正文

Go并发聊天室:从零构建实战

        大家好,今天我将分享一个使用Go语言从零开始构建的控制台并发聊天室项目。这个项目虽然简单,但它麻雀虽小五脏俱全,非常适合用来学习和实践Go语言强大的并发特性,尤其是 goroutinechannel 的使用。

一、项目亮点与功能特性

这个聊天室项目完全基于Go语言标准库实现,无需任何第三方依赖。它主要包含以下功能:

  • 多用户并发通信:支持多个客户端同时连接和收发消息。

  • 用户上线/下线广播:当有新用户加入或离开聊天室时,系统会自动向所有在线用户广播通知 。
  • 实时群组聊天:任何一个用户发送的消息都会被实时广播给所有其他在线用户 。

  • 查询在线用户:用户可以随时通过输入 who 命令,获取当前所有在线用户的列表 。

  • 在线改名:用户可以使用 rename|新名字 的格式,随时修改自己的昵称 。

  • 超时强制T出:为了管理资源,系统会自动T出长时间未活动的非活跃用户 。

二、项目整体架构

        项目的核心设计思想是“分而治之”,充分利用Go的并发能力。主协程负责监听和接受新的客户端连接,每当有新用户接入,就会为其创建一个独立的 goroutine (HandlerConnect) 来处理所有与该用户相关的交互。

消息处理的流程如下:

  1. 用户输入:各个客户端的 HandlerConnect 协程负责读取用户在终端输入的消息。

  2. 消息汇总HandlerConnect 将收到的消息写入一个全局的 message 通道。

  3. 中央广播:一个全局唯一的 Manager 管理者协程持续监听 message 通道。一旦收到消息,它会立即将该消息分发给所有在线用户的专属通道中。

  4. 消息写回:每个客户端还有一个专门的 WriteMsgToClient 协程,负责从自己的专属通道里读取消息,并将其最终写回到用户的终端界面上,完成消息显示。

三、核心代码解析

1. 用户结构体与全局变量

我们首先定义了用户的核心结构体 Client,以及用于通信的全局 mapchannel

// 创建用户结构体类型
type Client struct {C    chan string // 用户专属的、用于接收消息的channelName string      // 用户名Addr string      // 用户的网络地址
}// 创建全局map 储存在线用户
var onlineMap map[string]Client// 创建全局channel  传递用户消息,充当消息总线
var message = make(chan string)

2. 管理者协程 Manager

Manager 是整个聊天室的消息中枢。它在一个死循环中不断地从全局 message 通道读取消息,然后遍历 onlineMap,将消息并发地发送给每一个在线用户。

func Manager() {// 初始化 onlineMaponlineMap = make(map[string]Client)// 监听全局channel 中是否有数据for {msg := <-message // 无消息时会阻塞// 循环发送消息给所有在线用户for _, clnt := range onlineMap {clnt.C <- msg}}
}

3. 客户端处理协程 HandlerConnect

这是每个客户端的“管家”,也是项目中最核心的逻辑部分。它负责处理一个客户端从连接到断开的整个生命周期。

func HandlerConnect(conn net.Conn) {defer conn.Close()// ... 初始化Client并加入onlineMap ...// 启动一个专门给当前客户端写数据的go程go WriteMsgToClient(clnt, conn)// 广播用户上线message <- MakeMsg(clnt, "login")// 创建用于监听用户退出的channelisQuit := make(chan bool)// 创建用于判断用户是否活跃的channelhasData := make(chan bool)// 匿名go程,专门处理用户发送的消息go func() {buf := make([]byte, 4096)for {// ... 读取用户输入 conn.Read(buf) ...// 将读到的用户消息 写入message,或处理who/rename等命令message <- MakeMsg(clnt, msg)hasData <- true // 代表用户有活动}}()// 使用select监听各种状态for {select {case <-isQuit:// ... 处理用户退出逻辑 ...returncase <-hasData:// 此case仅用于重置下面的计时器,不做任何事case <-time.After(time.Second * 10): // 设置10秒超时// ... 处理超时T出逻辑 ...return}}
}

四、如何运行

1. 环境准备

请确保您已安装并配置好 Go 语言开发环境。

2. 获取源码

打开您的终端,使用 git 克隆项目代码。

git clone https://github.com/Joker-0111-G/Go-Concurrent-Chat-Room.git
3. 启动服务

进入项目目录,运行以下命令启动聊天室服务端。

cd Go-Concurrent-Chat-Room
go run 001ChatRoom.go

当您看到终端没有退出时,表示服务端已在 127.0.0.1:8000 端口上成功启动。

4. 连接客户端

您可以打开多个新的终端窗口,使用 telnetnc 命令来模拟多个用户连接到聊天室。

telnet 127.0.0.1 8000
nc 127.0.0.1 8000

每一个成功连接的终端窗口都代表一个在线用户。

五、项目源码地址

欢迎访问项目的 GitHub 仓库,获取完整源代码,也欢迎您提出宝贵的 Issue 或 PR!

  • GitHub地址: https://github.com/Joker-0111-G/Go-Concurrent-Chat-Room.git

六、总结

通过这个简单的并发聊天室项目,我们可以非常直观地学习到 Go 语言在并发编程中的优雅和强大。goroutine 轻量级线程模型和 channel 通信机制的结合,使得编写高并发应用变得异常轻松。希望这个项目能对您学习Go语言有所帮助!

http://www.xdnf.cn/news/15824.html

相关文章:

  • Shell脚本-tee工具
  • 小程序和H5数据mock配置过程
  • 前端环境搭建---基于SpringBoot+MySQL+Vue+ElementUI+Mybatis前后端分离面向小白管理系统搭建
  • LLM 的Top-P参数 是在LLM中的每一层发挥作用,还是最后一层?
  • SpringBoot五分钟快速入门指南
  • NW993NX584美光固态闪存NX559NX561
  • [故障诊断方向]基于二维时频图像和数据增强技术的轴承故障诊断模型
  • 数据分析综合应用 30分钟精通计划
  • 动态规划——数位DP经典题目
  • 量子计算与AI融合的技术突破与实践路径
  • 6. 装饰器模式
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘pillow’问题
  • 小架构step系列19:请求和响应
  • Java行为型模式---中介者模式
  • [故障诊断方向]SNNs:针对小样本轴承故障诊断的孪生神经网络模型
  • Selenium 中 findElement 方法全解析:定位网页元素的 7 种方式
  • BeanFactory 和 FactoryBean 的区别
  • Java行为型模式---访问者模式
  • 用Dynamic chunk去干掉tokenizer?
  • 从零入门:云迁移原理详解与华为Rainbow实战指南
  • 数据结构 队列
  • 信息系统风险的安全技术防范思路
  • 教育科技内容平台的破局之路:从组织困境到 UGC 生态的构建
  • CCF编程能力等级认证GESP—C++7级—20250628
  • [FFmpeg] AVFormatContext、AVInputFormat、AVOutputFormat | libavformat
  • 为任意Java程序配置Socks5与HTTP代理的方法
  • 2025年水安备考:水利水电安全员C类考试题
  • 基于Scrapy-Redis的分布式爬虫系统:工业级实现与深度优化
  • nodejs值process.kill
  • CCF编程能力等级认证GESP—C++8级—20250628