本系列注重于应用,至于内功心法(如:SCP进程模型啊,线程啊,用户态啊,内核态啊等等等)请读者自行补充
goroutine 是 golang 实现的协程,其特点是在语言层面就支持,使用起来非常方便
程序协程简单拓扑图
上源码
tcp.go
func StartCoreTCPServer() {
// 2S 之后才启动SOCKET服务
time.Sleep(time.Second * 2)
err := coreListener.Start()
if logs.ErrorProcess(err, "tcp start error") {
return
}
logs.Show("start tcp service @%s", port)
// 启动心跳检查
// 关闭默认心跳。2022-04-22
base.Go(heartBeatJob)
//接收多个用户
for {
// 其他业务处理,如:黑名单,限流等
//处理用户请求, 新建一个协程
base.Go(HandleConn, fd, conn)
// 其他业务
}
// HandleConn 处理用户请求
func HandleConn(id uint32, conn net.Conn) {
//声明一个临时缓冲区,用来存储被截断的数据
tmpBuffer := make([]byte, 0)
//声明一个管道用于接收解包的数据
readerChannel := make(chan []byte, 128)
//函数调用完毕,自动关闭conn
defer func() {
close(readerChannel)
//closeClient(id, nil)
}()
// 新启一个协程,处理具体的业务请求
base.Go(reader, id, conn.RemoteAddr().String(), readerChannel)
buf := make([]byte, 1024)
for {
if !clientManager.HasID(id) {
return
}
//读取用户数据
n, err := conn.Read(buf)
if err != nil {
closeClient(id, err)
return
}
tmpBuffer = tcp.CheckBuffer(append(tmpBuffer, buf[:n]...), readerChannel)
}
}
func reader(id uint32, addr string, readerChannel chan []byte) {
for {
select {
case data, ok := <-readerChannel:
if !ok || data == nil {
return
// 业务处理
}
}
}
}