Session增加唯一ID,拆分socket中的Read方法
增加ID为了以后判断闲置超时; 拆分Read方法方便扩展协议
本文代码查看github:
https://github.com/zboyco/go-server/tree/step-7
- 修改AppSession结构体,增加ID和activeDateTime属性,为超时管理做准备
//客户端结构体
type AppSession struct {
ID int64 //连接唯一标识
conn net.Conn //socket连接
activeDateTime time.Time //最后活跃时间
}
- 将socket.go 中接收数据的方法,移植到client.go中,作为AppSession的方法使用
//读取数据
func (session *AppSession) Read() ([]byte, error) {
//定义一个数据接收Buffer
var buf [10240]byte
//读取数据,io.Reader 需要传入一个byte切片
n, err := session.conn.Read(buf[0:])
if err != nil {
return nil, err
}
//更新最后活跃时间
session.activeDateTime = time.Now()
return buf[0:n], nil
}
client.go完整代码如下:
package server
import (
"net"
"time"
)
//客户端结构体
type AppSession struct {
ID int64 //连接唯一标识
conn net.Conn //socket连接
activeDateTime time.Time //最后活跃时间
}
//发送数据
func (session *AppSession) Send(buf []byte) {
session.conn.Write(buf)
//更新最后活跃时间
session.activeDateTime = time.Now()
}
//读取数据
func (session *AppSession) Read() ([]byte, error) {
//定义一个数据接收Buffer
var buf [10240]byte
//读取数据,io.Reader 需要传入一个byte切片
n, err := session.conn.Read(buf[0:])
if err != nil {
return nil, err
}
//更新最后活跃时间
session.activeDateTime = time.Now()
return buf[0:n], nil
}
修改socket.go中handleClient函数,执行AppSession的Read来获取数据
socket.go 完整代码如下:
package server
import (
"fmt"
"net"
"time"
)
//服务结构
type Server struct {
ip string
port int
clientCounter int64
OnError func(error)
OnMessage func(*AppSession, []byte)
}
//新建一个服务
func New(ip string, port int) *Server {
return &Server{
ip: ip,
port: port,
clientCounter: 0,
}
}
//开始监听
func (server *Server) Start() {
//定义一个本机端口
localAddress, _ := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", server.ip, server.port))
//监听端口
tcpListener, err := net.ListenTCP("tcp", localAddress)
if err != nil {
fmt.Println("监听出错, ", err)
if server.OnError != nil {
server.OnError(err)
}
return
}
//程序返回后关闭socket
defer tcpListener.Close()
for {
fmt.Println("等待客户连接...")
//开始接收连接
conn, err := tcpListener.Accept()
if err != nil {
fmt.Println("客户连接失败, ", err)
if server.OnError != nil {
server.OnError(err)
}
continue
}
//客户端ID数+1
server.clientCounter++
appSession := &AppSession{
ID: server.clientCounter,
conn: conn,
activeDateTime: time.Now(),
}
//启用goroutine处理
go handleClient(server, appSession)
}
}
//读取数据
func handleClient(server *Server, session *AppSession) {
//获取连接地址
remoteAddr := session.conn.RemoteAddr()
fmt.Println("客户[", session.ID, "]地址:", remoteAddr)
for {
fmt.Println("等待接收客户[", session.ID, "]的数据...", session.activeDateTime)
bytes, err := session.Read()
if err != nil {
fmt.Println("客户[", session.ID, "]数据接收错误, ", err)
if server.OnError != nil {
server.OnError(err)
}
return
}
if server.OnMessage == nil {
fmt.Println("错误,未找到数据处理方法!")
continue
}
server.OnMessage(session, bytes)
}
}