📈【Go 实践】实现一个简单的多人聊天室

本文使用 go 实现了一个多人聊天室,参考文章为 Writing a Chat Server in Go ,点击查看 中文翻译版

本文的特点在于:将原始项目分为自底向上的若干个阶段,新手可以一步步地实现系统的不同模块,逐渐掌握相应知识点。 源码 里有详细的注释,引导你在不看源代码的情况下自己实现相应代码。

本文假设你:

  • 了解 go 语言的基本语法
  • 了解 git 的使用

完成本项目,你将学会这些内容:

net

运行

运行环境:go 1.13.1

  1. 打开 GO111MODULE ,运行 go mod download 安装依赖
  2. 启动 server: server/cmd 目录下运行 go run main.go
  3. 启动 client: tui/cmd 目录下运行 go run main.go -server=localhost:3333 ,可以在多个窗口启动不同的客户端

学习方法

本项目共有 5 个分支,对应 4 个阶段。这 5 个分支依次为:

v0-template-code
v1-protocol-reader-writer
v2-server-implementation
v3-client-implementation
v4-gob-protocol

对应的阶段为:

  1. 实现基于字符串的通信协议:v0 -> v1
  2. 实现服务端:v1 -> v2
  3. 实现客户端:v2 -> v3
  4. 使用 gob 作为通信协议:v3 -> v4

建议从 v0 开始,根据注释内容依次实现每个模块。如果实在摸不着头脑,可以查看 master 分支下的代码 获得提示。

步骤简介

1. 实现协议

运行:

git checkout v0-template-code
复制代码

在这一步我们要实现通信协议。TCP 传输的都是无格式的字节流,我们需要定义这些字符串的格式,以在客户端和服务端能解析出相应的命令与参数。

客户端与服务端通过 TCP 传输的是字符串,因此需要规定一个将字符串解析为命令的协议。

约定一条命令的格式如下所示:

[命令类型] [参数1] [参数2] ... [参数n]\n
复制代码

每条命令以换行符结尾。

命令一共有三种:

NAME
SEND
MESSAGE

比如客户端发送聊天消息的命令为:

SEND somemessage\n
复制代码

服务端广播消息给其他用户的命令为:

MESSAGE username somemessage\n
复制代码

protocol/command.go 中定义了命令的类型。需要实现 protocol/reader.goprotocol/writer.go 中的相应方法。

2. 实现服务端

运行:

git checkout v1-protocol-reader-writer
复制代码

在这一步我们要实现服务端。服务端接受客户端的连接请求,并保存所有连接以在之后向客户端发送数据。

服务端的工作流程为:

  1. Listen:启动一个服务器,监听一个端口
  2. Accept & Serve:与客户端建立一个连接,并为其提供服务
  3. Remove:在客户端退出连接后,删除该客户的的连接
  4. Close:停止监听端口,关闭服务器

服务端与客户端的交互有:

  1. 接受客户端发来的消息,并广播(broadcast)给其他客户端
  2. 设置某个客户端的名称

server/server.go 将服务端的行为定义为一个接口, server/tcp_server.go 为相应的实现。

实现客户端

运行:

git checkout v2-server-implementation
复制代码

在这一步我们要实现客户端。客户端其实比较简单,只需要连接到服务端,然后向服务端发送消息或接收服务端的消息。这部分的工作主要在于 UI 的实现,不过我没有单独抽离它。感兴趣的读者可以查看 tui/ 目录下的源码。

使用 gob 作为通信协议

运行:

git checkout v3-client-implementation
复制代码

在这一步我们要使用 gob 作为通信协议,替换原来的基于字符串的协议。只需要修改 protocol/reader.goprotocol/writer.goRead()Write() 方法,涉及到 gob 的两组方法: NewEncoder/EncoderNewDecoder/Decode 。是不是很方便!

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章