基于 golang 的即时通信系统

一、部署运行(Windows)

进入 0.9 版本目录下

1、首先将 client.go 中的 main 函数进行注释,对 server.go、user.go、main.go 进行编译

go build -o server.exe server.go main.go user.go

编译后会生成一个 server.exe 文件

2、将 main.go 中的 main 函数进行注释,再将 client.go 中的 main 函数解开注释,对 client.go 进行编译

go build -o client.exe client.go

生成一个 client.exe 文件

3、启动一个终端,然后执行:.\server 命令,启动服务端

4、另外启动一个或多个终端:执行:.\client 命令,启动客户端,这样启动默认是连接 127.0.0.1:8888

也可以指定 ip 和 port:

.\client -ip IP地址 -port 端口号

但此处指定的 ip 地址和端口号必须和 main.go 中设置的服务端 ip 和 port 一致

package main

func main() {
    // 指定服务端ip和port
    server := NewServer("127.0.0.1", 8888)
    server.Start()
}

二、主要架构

基本的通信模式

在 Server 中维护了一个 map,用来存储所有的在线用户,以用户名作为 key,以用户实体作为 value,是一个指针类型,存储的是用户的地址

Server 中还维护了一个通道 Channel,该通道负责消息广播。会启动一个 goroutine 去阻塞该通道,不断尝试去从该通道中读取数据,一旦读取到数据,就将其发送给所有在线用户中维护的 Channel

每个用户 User 中都维护了一个通道 Channel,和一个连接 Conn。该通道也由一个 goroutine 管理,会不断尝试从该通道中读取消息,没有读到消息就阻塞在那里,一旦读到消息,就将该消息通过 Conn 连接写给该 User 对应的客户端 Client

每个 User 都有一个对应的客户端 Client,客户端 Client 通过 net.Dial 进行服务端的连接,服务端则通过 net.Listen 监听客户端的连接

三、主要功能

模式的选择主要通过 Client 中维护的一个整型 flag,该 flag 用来接收用户的输入

  • 若 flag 等于 1,则代表选择公聊模式
  • 若 flag 等于 2,则代表选择私聊模式
  • 若 flag 等于 3,则代表要修改用户名
  • 若 flag 等于 0,则代表退出系统

客户端 Client 会尝试对服务端 Server 进行连接,连接成功后会获得一个 Conn,之后便是启动客户端的业务。而在正式启动客户端业务之前,会另外开启一个 goroutine 去并发处理服务端 Server 返回的消息

在业务中会不断循环去判断 flag 是否为 0,若为 0,则代表用户要退出系统,此时结束循环,退出整个业务

3.1 公聊模式

当用户输入数字 1 后,则进入公聊模式

接收到用户的输入后,首先判断其是否为 exit,exit 代表退出当前模式

然后判断消息是否为空,不为空就将消息通过 Conn 写给服务端。在发送之前会先对消息进行指定的格式拼接,因为每个功能都会有设置好的指令

服务端会启动一个 goroutine 去从该 Conn 中读取消息,对该消息进行专门处理,判断该消息的格式是否符合公聊模式设置的格式,若符合,则将该消息进行广播,也就是将该消息写入服务端维护的 Channel 之中,这个 Channel 是由一个 goroutine 进行监听的,读到消息就会将其发送给所有在线用户,用户通过 Conn 向对应的客户端进行回写操作

并且用户上线和用户下线的消息也都是进行广播的,用户上线则将该用户加到 map 中,反之则将其删除

3.2 私聊模式

私聊模式功能也是类似,拼接好要发送的消息,进行发送

发送私聊指令之前,会先发送一个查询所有在线用户的指令,查出所有在线用户,提供选择

服务端进行处理。从拼接的消息中截取用户输入的用户名,表示该用户要和哪一个用户进行私聊

通过该用户名从 map 中获取用户对象,再截取消息内容

最后将该消息发送给获取的用户对象

3.3 更改用户名

该功能也是类似,将拼接的消息发送给服务端

服务端收到消息进行处理

判断该用户名是否已存在,若已存在,则向该用户发送消息提示

否则就进行修改即可

GitHub

View Github