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

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.dtcms.com/a/289127.html

相关文章:

  • Mysql(事务)
  • 30个常用的Linux命令汇总和实战场景示例
  • 30天打牢数模基础-粒子群算法讲解
  • 详解Mysql索引合并
  • Jetpack - ViewModel、LiveData、DataBinding(数据绑定、双向数据绑定)
  • langchain调用本地ollama语言模型和嵌入模型
  • 梯度提升之原理
  • COGNEX康耐视IS5403-01智能相机加Navitar 18R00 LR1010WM52镜头
  • React 英语打地鼠游戏——一个寓教于乐的英语学习游戏
  • [Windows] Bili视频转图文笔记 v1.7.5
  • 网鼎杯2020青龙组notes复现
  • 7. 命令模式
  • Modbus Slave 使用教程:快速搭建模拟从站进行测试与开发
  • Ribbon轮询实现原理
  • Unity笔记——Unity 封装方法指南
  • day24——Java高级技术深度解析:单元测试、反射、注解与动态代理
  • [Python] -项目实战类3- 用Python制作一个记事本应用
  • CVE-2022-41128
  • Python数据处理库与语法总结
  • API获取及调用(以豆包为例实现图像分析)
  • FreeRTOS任务创建与删除
  • 掌握配置文件(三):运用Profile实现多环境配置隔离
  • 三级知识点汇总(详解)【c++】——3
  • 让不符合要求的任何电脑升级Windows11
  • 《通信原理》学习笔记——第五章
  • 开源安全大模型Foundation-Sec 8B的安全实践
  • 分享如何在保证画质的前提下缩小视频体积实用方案
  • 【记某次线上消息积压问题排查及解决方案】
  • 基于Pytorch的人脸识别程序
  • 基于FPGA实现ARINC818