aceld
6 years ago
3 changed files with 177 additions and 20 deletions
@ -0,0 +1,25 @@ |
|||||
|
package ziface |
||||
|
|
||||
|
import "net" |
||||
|
|
||||
|
//定义连接接口
|
||||
|
type IConnection interface { |
||||
|
//启动连接,让当前连接开始工作
|
||||
|
Start() |
||||
|
//停止连接,结束当前连接状态M
|
||||
|
Stop() |
||||
|
//从当前连接获取原始的socket TCPConn
|
||||
|
GetTCPConnection() *net.TCPConn |
||||
|
//获取当前连接ID
|
||||
|
GetConnID() uint32 |
||||
|
//获取远程客户端地址信息
|
||||
|
RemoteAddr() net.Addr |
||||
|
//直接将数据发送数据给远程的TCP客户端
|
||||
|
Send(data []byte) error |
||||
|
//将数据发送给缓冲队列,通过专门从缓冲队列读数据的go写给客户端
|
||||
|
SendBuff(data []byte) error |
||||
|
} |
||||
|
|
||||
|
//定义一个统一处理链接业务的接口
|
||||
|
type HandFunc func(*net.TCPConn, []byte, int) error |
||||
|
|
@ -0,0 +1,131 @@ |
|||||
|
package znet |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"net" |
||||
|
"zinx/ziface" |
||||
|
) |
||||
|
|
||||
|
type Connection struct { |
||||
|
//当前连接的socket TCP套接字
|
||||
|
Conn *net.TCPConn |
||||
|
//当前连接的ID 也可以称作为SessionID,ID全局唯一
|
||||
|
ConnID uint32 |
||||
|
//当前连接的关闭状态
|
||||
|
isClosed bool |
||||
|
|
||||
|
//该连接的处理方法api
|
||||
|
handleAPI ziface.HandFunc |
||||
|
|
||||
|
//告知该链接已经退出/停止的channel
|
||||
|
ExitBuffChan chan bool |
||||
|
|
||||
|
//给缓冲队列发送数据的channel,
|
||||
|
// 如果向缓冲队列发送数据,那么把数据发送到这个channel下
|
||||
|
// SendBuffChan chan []byte
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
//创建连接的方法
|
||||
|
func NewConntion(conn *net.TCPConn, connID uint32, callback_api ziface.HandFunc) *Connection{ |
||||
|
c := &Connection{ |
||||
|
Conn: conn, |
||||
|
ConnID: connID, |
||||
|
isClosed: false, |
||||
|
handleAPI: callback_api, |
||||
|
ExitBuffChan: make(chan bool, 1), |
||||
|
// SendBuffChan: make(chan []byte, 512),
|
||||
|
} |
||||
|
|
||||
|
return c |
||||
|
} |
||||
|
|
||||
|
func (c *Connection) StartReader() { |
||||
|
fmt.Println("Reader Goroutine is running") |
||||
|
defer fmt.Println(c.RemoteAddr().String(), " conn reader exit!") |
||||
|
defer c.Stop() |
||||
|
|
||||
|
for { |
||||
|
//读取我们最大的数据到buf中
|
||||
|
buf := make([]byte, 512) |
||||
|
cnt, err := c.Conn.Read(buf) |
||||
|
if err != nil { |
||||
|
fmt.Println("recv buf err ", err) |
||||
|
c.ExitBuffChan <- true |
||||
|
continue |
||||
|
} |
||||
|
//调用当前链接业务
|
||||
|
if err := c.handleAPI(c.Conn, buf, cnt); err !=nil { |
||||
|
fmt.Println("connID ", c.ConnID, " handle is error") |
||||
|
c.ExitBuffChan <- true |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
//启动连接,让当前连接开始工作
|
||||
|
func (c *Connection) Start() { |
||||
|
|
||||
|
//开启处理该链接读取到客户端数据之后的请求业务
|
||||
|
go c.StartReader() |
||||
|
|
||||
|
for { |
||||
|
select { |
||||
|
case <- c.ExitBuffChan: |
||||
|
//得到退出消息,不再阻塞
|
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//1 开启用于写回客户端数据流程的Goroutine
|
||||
|
//2 开启用户从客户端读取数据流程的Goroutine
|
||||
|
} |
||||
|
|
||||
|
//停止连接,结束当前连接状态M
|
||||
|
func (c *Connection) Stop() { |
||||
|
//1. 如果当前链接已经关闭
|
||||
|
if c.isClosed == true { |
||||
|
return |
||||
|
} |
||||
|
c.isClosed = true |
||||
|
|
||||
|
//TODO Connection Stop() 如果用户注册了该链接的关闭回调业务,那么在此刻应该显示调用
|
||||
|
|
||||
|
// 关闭socket链接
|
||||
|
c.Conn.Close() |
||||
|
|
||||
|
//通知从缓冲队列读数据的业务,该链接已经关闭
|
||||
|
c.ExitBuffChan <- true |
||||
|
|
||||
|
//关闭该链接全部管道
|
||||
|
//close(c.ExitBuffChan)
|
||||
|
//close(c.SendBuffChan)
|
||||
|
} |
||||
|
|
||||
|
//从当前连接获取原始的socket TCPConn
|
||||
|
func (c *Connection) GetTCPConnection() *net.TCPConn { |
||||
|
return c.Conn |
||||
|
} |
||||
|
|
||||
|
//获取当前连接ID
|
||||
|
func (c *Connection) GetConnID() uint32{ |
||||
|
return c.ConnID |
||||
|
} |
||||
|
|
||||
|
//获取远程客户端地址信息
|
||||
|
func (c *Connection) RemoteAddr() net.Addr { |
||||
|
return c.Conn.RemoteAddr() |
||||
|
} |
||||
|
|
||||
|
//直接将数据发送数据给远程的TCP客户端
|
||||
|
func (c *Connection) Send(data []byte) error { |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
//将数据发送给缓冲队列,通过专门从缓冲队列读数据的go写给客户端
|
||||
|
func (c *Connection) SendBuff(data []byte) error { |
||||
|
return nil |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue