go-study/zinx/znet/connection.go
2025-09-14 13:59:56 +08:00

112 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package znet
import (
"fmt"
"go-study/zinx/ziface"
"net"
)
type Connection struct {
// 该连接的 TCP Socket 套接字
Conn *net.TCPConn
// 连接 ID全局唯一
ConnID uint32
// 该连接的关闭状态
IsClosed bool
// 该连接的处理方法 Router
Router ziface.IRouter
// 该连接的退出消息通知 channel
ExitBuffChan chan struct{}
}
// NewConnection 创建连接的方法
func NewConnection(conn *net.TCPConn, connID uint32, router ziface.IRouter) ziface.IConnection {
return &Connection{
Conn: conn,
ConnID: connID,
IsClosed: false,
Router: router,
ExitBuffChan: make(chan struct{}, 1),
}
}
// StartReader 处理连接读数据的业务方法
func (c *Connection) StartReader() {
fmt.Println("Reader Goroutine is running")
defer fmt.Println("connID =", c.ConnID, "Reader is exit, remote addr is", c.RemoteAddr().String())
defer c.Stop()
for {
// 读取客户端数据到buf中最大512字节
buf := make([]byte, 512)
cnt, err := c.Conn.Read(buf)
if err != nil {
fmt.Println("recv buf err", err)
c.ExitBuffChan <- struct{}{}
continue
}
req := Request{
conn: c,
data: buf[:cnt],
}
// 从路由中找到注册绑定的 Conn 对应的 router 调用
go func(request ziface.IRequest) {
// 执行注册的路由方法
c.Router.PreHandle(request)
c.Router.Handle(request)
c.Router.PostHandle(request)
}(&req)
}
}
// Start 启动连接,让当前连接开始工作
func (c *Connection) Start() {
// 启动当前连接的读数据业务
go c.StartReader()
for {
select {
case <-c.ExitBuffChan:
// 得到退出消息,不再阻塞
return
}
}
}
// Stop 停止连接,结束当前连接状态
func (c *Connection) Stop() {
if c.IsClosed {
return
}
c.IsClosed = true
// TODO 如果用户注册了该连接的关闭回调业务,那么在此刻应该显式调用
// 关闭 Socket 连接
_ = c.Conn.Close()
// 通知从缓冲队列读取数据的业务,该连接已经关闭
c.ExitBuffChan <- struct{}{}
// 关闭该连接的全部管道
close(c.ExitBuffChan)
}
// GetTCPConnection 获取当前连接的 TCP Socket 套接字
func (c *Connection) GetTCPConnection() *net.TCPConn {
return c.Conn
}
// GetConnID 获取当前连接 ID
func (c *Connection) GetConnID() uint32 {
return c.ConnID
}
// RemoteAddr 获取远程客户端地址信息
func (c *Connection) RemoteAddr() net.Addr {
return c.Conn.RemoteAddr()
}