112 lines
2.4 KiB
Go
112 lines
2.4 KiB
Go
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()
|
||
}
|