Skip to content

Releases: Sleepwal/SleepXLink

V1.0

Choose a tag to compare

@Sleepwal Sleepwal released this 28 Dec 12:23

Sinx

学习zinx1.0开源框架

V1.0 链接管理和连接属性设置

使用该框架开发

配置文件

host: 127.0.0.1
port: 8888
name: Sinx V1.0 demoServerApp
maxConn: 3
workerPoolSize: 10

server.go

func main() {
	server := snet.NewServer()

	//注册链接hook回调函数
	server.SetOnConnStart(DoConnectionBegin)
	server.SetOnConnStop(DoConnectionLast)

	//添加自定义router
	server.AddRouter(0, &PingRouter{})
	server.AddRouter(1, &HelloRouter{})
	server.Serve()
}

// ping 自定义路由
type PingRouter struct {
	snet.BaseRouter
}

func (pr *PingRouter) Handle(request iface.IRequest) {
	fmt.Println("Call Ping Router Handle...")
	// 1.读取客户端数据
	fmt.Println("recv from client: msgID = ", request.GetMsgID(), ", data = ", string(request.GetData()))

	// 2.回显ping
	err := request.GetConnection().SendMsg(200, []byte("ping...ping...\n"))
	if err != nil {
		fmt.Println("cal back handle error: ", err)
	}
}

// hello 自定义路由
type HelloRouter struct {
	snet.BaseRouter
}

func (hr *HelloRouter) Handle(request iface.IRequest) {
	fmt.Println("Call Hello Router Handle...")
	// 1.读取客户端数据
	fmt.Println("recv from client: msgID = ", request.GetMsgID(), ", data = ", string(request.GetData()))

	// 2.回显ping
	err := request.GetConnection().SendMsg(500, []byte("Hello Sinx!\n"))
	if err != nil {
		fmt.Println("cal back handle error: ", err)
	}
}

// 创建连接的时候执行
func DoConnectionBegin(conn iface.IConnection) {
	fmt.Println("DoConnecionBegin is Called ... ")

	//=============设置两个链接属性,在连接创建之后===========
	fmt.Println("Set conn Name, Home done!")
	conn.SetProperty("Name", "SleepWalker")
	conn.SetProperty("Home", "https://github.com/Sleepwal")
	//===================================================

	err := conn.SendMsg(2, []byte("DoConnection BEGIN..."))
	if err != nil {
		fmt.Println(err)
	}
}

// 连接断开的时候执行
func DoConnectionLast(conn iface.IConnection) {
	//============在连接销毁之前,查询conn的Name,Home属性=====
	if name, err := conn.GetProperty("Name"); err == nil {
		fmt.Println("Conn Property Name = ", name)
	}

	if home, err := conn.GetProperty("Home"); err == nil {
		fmt.Println("Conn Property Home = ", home)
	}
	//===================================================

	fmt.Println("DoConneciotnLost is Called ... ")
}

client.go

/*
模拟客户端
*/
func main() {
	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:8888")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for i := 0; i < 5; i++ {
		//发封包message消息
		msg, _ := snet.Pack(snet.NewMessage(uint32(i)%2, []byte(fmt.Sprintf("Sinx Client%d Test Message", i))))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, snet.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		recvMsg, err := snet.UnPack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if recvMsg.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			recvMsg.SetData(make([]byte, recvMsg.GetDataLen()))

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, recvMsg.GetData())
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", recvMsg.GetMsgId(),
				", len=", recvMsg.GetDataLen(),
				", data=", string(recvMsg.GetData()))
		}

		time.Sleep(1 * time.Second)
	}
}

v0.8

Choose a tag to compare

@Sleepwal Sleepwal released this 21 Dec 11:52

开辟任务池和限定业务Goroutine

ChangeLog

MsgHandle类中

属性

  • 添加worker任务池(消息队列)TaskQueue
  • 添加worker池的数量WorkerPoolSize,默认10

方法

  • 启动worker工作池:StartWorkerPool
  • 启动一个worker工作流程:StartOneWorker
  • 添加请求到TaskQueue中:AddRequestToTaskQueue

集成到Sinx

  • 添加全局变量
    • WorkerPoolSize
    • MaxWorkerTaskLen
  • Sever启动时,开启worker工作池
  • Connection中,
    • 如果开启工作池,交给工作池处理
    • 否则直接处理

V0.7

Choose a tag to compare

@Sleepwal Sleepwal released this 20 Dec 15:56

V0.7

使用同V0.6

配置文件

host: 127.0.0.1
port: 8888
name: Sinx V0.7 demoServerApp
maxConn: 3

V0.6

Choose a tag to compare

@Sleepwal Sleepwal released this 20 Dec 15:54

多路由模式

使用框架

  • Connection中读、写分离
    • 添加一个管道msgChan,读、写Goroutine进行通信

server.go

func main() {
	server := snet.NewServer()
	//添加自定义router
	server.AddRouter(0, &PingRouter{})
	server.AddRouter(1, &HelloRouter{})
	server.Serve()
}

// ping 自定义路由
type PingRouter struct {
	snet.BaseRouter
}

func (pr *PingRouter) Handle(request iface.IRequest) {
	fmt.Println("Call Ping Router Handle...")
	// 1.读取客户端数据
	fmt.Println("recv from client: msgID = ", request.GetMsgID(), ", data = ", string(request.GetData()))

	// 2.回显ping
	err := request.GetConnection().SendMsg(200, []byte("ping...ping...\n"))
	if err != nil {
		fmt.Println("cal back handle error: ", err)
	}
}

// hello 自定义路由
type HelloRouter struct {
	snet.BaseRouter
}

func (hr *HelloRouter) Handle(request iface.IRequest) {
	fmt.Println("Call Hello Router Handle...")
	// 1.读取客户端数据
	fmt.Println("recv from client: msgID = ", request.GetMsgID(), ", data = ", string(request.GetData()))

	// 2.回显ping
	err := request.GetConnection().SendMsg(500, []byte("Hello Sinx!\n"))
	if err != nil {
		fmt.Println("cal back handle error: ", err)
	}
}

client.go

/*
模拟客户端
*/
func main() {
	fmt.Println("Client Test ... start")
	//3秒之后发起测试请求,给服务端开启服务的机会
	time.Sleep(3 * time.Second)

	conn, err := net.Dial("tcp", "127.0.0.1:8888")
	if err != nil {
		fmt.Println("client start err, exit!")
		return
	}

	for i := 0; i < 5; i++ {
		//发封包message消息
		msg, _ := snet.Pack(snet.NewMessage(uint32(i)%2, []byte(fmt.Sprintf("Sinx Client%d Test Message", i))))
		_, err := conn.Write(msg)
		if err != nil {
			fmt.Println("write error err ", err)
			return
		}

		//先读出流中的head部分
		headData := make([]byte, snet.GetHeadLen())
		_, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
		if err != nil {
			fmt.Println("read head error")
			break
		}
		//将headData字节流 拆包到msg中
		recvMsg, err := snet.UnPack(headData)
		if err != nil {
			fmt.Println("server unpack err:", err)
			return
		}

		if recvMsg.GetDataLen() > 0 {
			//msg 是有data数据的,需要再次读取data数据
			recvMsg.SetData(make([]byte, recvMsg.GetDataLen()))

			//根据dataLen从io中读取字节流
			_, err := io.ReadFull(conn, recvMsg.GetData())
			if err != nil {
				fmt.Println("server unpack data err:", err)
				return
			}

			fmt.Println("==> Recv Msg: ID=", recvMsg.GetMsgId(),
				", len=", recvMsg.GetDataLen(),
				", data=", string(recvMsg.GetData()))
		}

		time.Sleep(1 * time.Second)
	}
}

V0.5

Choose a tag to compare

@Sleepwal Sleepwal released this 20 Dec 03:37

Message消息模块

  • 解决TCP粘包问题
  • 自定义消息包 【DataLen | MsgID | MsgData】
  • 定义对应的封包、拆包方法

V0.4

Choose a tag to compare

@Sleepwal Sleepwal released this 16 Dec 08:58

全局配置模块

读取conf/sinx.yaml配置文件

host: 127.0.0.1
port: 8888
name: sinx demoServerApp
version: V0.4
maxConn: 3

V0.3

Choose a tag to compare

@Sleepwal Sleepwal released this 16 Dec 04:24

基础Router模块

  • Request请求封装、基础Router模块

V0.2

Choose a tag to compare

@Sleepwal Sleepwal released this 14 Dec 05:34

链接模块

V0.1

Choose a tag to compare

@Sleepwal Sleepwal released this 14 Dec 05:27

基础Server模块