Browse Source

Merge pull request #59 from adsian/server_test

code optimization
master
Gao Zhihui 5 years ago
committed by GitHub
parent
commit
c203901bd5
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      GNUmakefile
  2. 14
      examples/zinx_version_ex/ZinxV0.10Test/Client0.go
  3. 14
      examples/zinx_version_ex/ZinxV0.10Test/Client1.go
  4. 2
      examples/zinx_version_ex/ZinxV0.10Test/Server.go
  5. 14
      examples/zinx_version_ex/ZinxV0.11Test/Client0.go
  6. 14
      examples/zinx_version_ex/ZinxV0.11Test/Client1.go
  7. 2
      examples/zinx_version_ex/ZinxV0.11Test/Server.go
  8. 14
      examples/zinx_version_ex/ZinxV0.1Test/Client.go
  9. 3
      examples/zinx_version_ex/ZinxV0.1Test/Server.go
  10. 14
      examples/zinx_version_ex/ZinxV0.2Test/Client.go
  11. 3
      examples/zinx_version_ex/ZinxV0.2Test/Server.go
  12. 14
      examples/zinx_version_ex/ZinxV0.3Test/Client.go
  13. 9
      examples/zinx_version_ex/ZinxV0.3Test/Server.go
  14. 14
      examples/zinx_version_ex/ZinxV0.4Test/Client.go
  15. 14
      examples/zinx_version_ex/ZinxV0.5Test/Client.go
  16. 8
      examples/zinx_version_ex/ZinxV0.5Test/Server.go
  17. 14
      examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/Client0.go
  18. 14
      examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/Client1.go
  19. 14
      examples/zinx_version_ex/ZinxV0.8Test/Client0.go
  20. 14
      examples/zinx_version_ex/ZinxV0.8Test/Client1.go
  21. 14
      examples/zinx_version_ex/ZinxV0.9Test/Client0.go
  22. 14
      examples/zinx_version_ex/ZinxV0.9Test/Client1.go
  23. 4
      examples/zinx_version_ex/datapackDemo/Client.go
  24. 2
      examples/zinx_version_ex/datapackDemo/Server.go
  25. 2
      examples/zinx_version_ex/protoDemo/main.go
  26. 4
      utils/globalobj.go
  27. 5
      ziface/iconnection.go
  28. 4
      ziface/iconnmanager.go
  29. 10
      ziface/idatapack.go
  30. 14
      ziface/imessage.go
  31. 12
      ziface/imsghandler.go
  32. 9
      ziface/irequest.go
  33. 4
      ziface/irouter.go
  34. 8
      ziface/iserver.go
  35. 2
      zinx_app_demo/mmo_game/api/move.go
  36. 4
      zinx_app_demo/mmo_game/api/world_chat.go
  37. 2
      zinx_app_demo/mmo_game/client_AI_robot.go
  38. 4
      zinx_app_demo/mmo_game/core/aoi.go
  39. 6
      zinx_app_demo/mmo_game/core/aoi_test.go
  40. 4
      zinx_app_demo/mmo_game/core/player.go
  41. 4
      zinx_app_demo/mmo_game/server.go
  42. 2
      zlog/stdzlog.go
  43. 27
      zlog/zlogger.go
  44. 6
      zlog/zlogger_test.go
  45. 8
      znet/connection.go
  46. 11
      znet/connmanager.go
  47. 10
      znet/datapack.go
  48. 4
      znet/message.go
  49. 27
      znet/msghandler.go
  50. 10
      znet/request.go
  51. 8
      znet/router.go
  52. 60
      znet/server.go
  53. 40
      znet/server_test.go
  54. 12
      ztimer/delayfunc.go
  55. 4
      ztimer/delayfunc_test.go
  56. 16
      ztimer/timer.go
  57. 11
      ztimer/timer_test.go
  58. 19
      ztimer/timerscheduler.go
  59. 24
      ztimer/timerscheduler_test.go
  60. 12
      ztimer/timewheel.go
  61. 17
      ztimer/timewheel_test.go

11
GNUmakefile

@ -0,0 +1,11 @@
# gofmt格式化
# run in terminal:
# make fmt
# win系统中,在git bash中如果出现make包没有找到
# 管理员运行git bash,运行以下命令
# choco install make
GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor)
fmt:
gofmt -w $(GOFMT_FILES)

14
examples/zinx_version_ex/ZinxV0.10Test/Client0.go

@ -2,22 +2,22 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"time"
"github.com/aceld/zinx/znet"
)
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -26,9 +26,9 @@ func main() {
for {
//发封包message消息
dp := znet.NewDataPack()
msg, _ := dp.Pack(znet.NewMsgPackage(0,[]byte("Zinx V0.8 Client0 Test Message")))
msg, _ := dp.Pack(znet.NewMsgPackage(0, []byte("Zinx V0.8 Client0 Test Message")))
_, err := conn.Write(msg)
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
@ -62,6 +62,6 @@ func main() {
fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
}
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

14
examples/zinx_version_ex/ZinxV0.10Test/Client1.go

@ -2,22 +2,22 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"time"
"github.com/aceld/zinx/znet"
)
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -26,9 +26,9 @@ func main() {
for n := 3; n >= 0; n-- {
//发封包message消息
dp := znet.NewDataPack()
msg, _ := dp.Pack(znet.NewMsgPackage(1,[]byte("Zinx V0.8 Client1 Test Message")))
msg, _ := dp.Pack(znet.NewMsgPackage(1, []byte("Zinx V0.8 Client1 Test Message")))
_, err := conn.Write(msg)
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
@ -62,6 +62,6 @@ func main() {
fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
}
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

2
examples/zinx_version_ex/ZinxV0.10Test/Server.go

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

14
examples/zinx_version_ex/ZinxV0.11Test/Client0.go

@ -2,22 +2,22 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"time"
"github.com/aceld/zinx/znet"
)
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -26,9 +26,9 @@ func main() {
for {
//发封包message消息
dp := znet.NewDataPack()
msg, _ := dp.Pack(znet.NewMsgPackage(0,[]byte("Zinx V0.8 Client0 Test Message")))
msg, _ := dp.Pack(znet.NewMsgPackage(0, []byte("Zinx V0.8 Client0 Test Message")))
_, err := conn.Write(msg)
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
@ -62,6 +62,6 @@ func main() {
fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
}
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

14
examples/zinx_version_ex/ZinxV0.11Test/Client1.go

@ -2,22 +2,22 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"time"
"github.com/aceld/zinx/znet"
)
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -26,9 +26,9 @@ func main() {
for n := 3; n >= 0; n-- {
//发封包message消息
dp := znet.NewDataPack()
msg, _ := dp.Pack(znet.NewMsgPackage(1,[]byte("Zinx V0.8 Client1 Test Message")))
msg, _ := dp.Pack(znet.NewMsgPackage(1, []byte("Zinx V0.8 Client1 Test Message")))
_, err := conn.Write(msg)
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
@ -62,6 +62,6 @@ func main() {
fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
}
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

2
examples/zinx_version_ex/ZinxV0.11Test/Server.go

@ -64,7 +64,7 @@ func DoConnectionBegin(conn ziface.IConnection) {
//连接断开的时候执行
func DoConnectionLost(conn ziface.IConnection) {
//在连接销毁之前,查询conn的Name,Home属性
if name, err:= conn.GetProperty("Name"); err == nil {
if name, err := conn.GetProperty("Name"); err == nil {
zlog.Error("Conn Property Name = ", name)
}

14
examples/zinx_version_ex/ZinxV0.1Test/Client.go

@ -8,14 +8,14 @@ import (
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -23,20 +23,20 @@ func main() {
for {
_, err := conn.Write([]byte("hahaha"))
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
buf :=make([]byte, 512)
buf := make([]byte, 512)
cnt, err := conn.Read(buf)
if err != nil {
fmt.Println("read buf error ")
return
}
fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)
fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

3
examples/zinx_version_ex/ZinxV0.1Test/Server.go

@ -4,9 +4,6 @@ import (
"github.com/aceld/zinx/znet"
)
//Server 模块的测试函数
func main() {

14
examples/zinx_version_ex/ZinxV0.2Test/Client.go

@ -8,14 +8,14 @@ import (
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -23,20 +23,20 @@ func main() {
for {
_, err := conn.Write([]byte("hahaha"))
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
buf :=make([]byte, 512)
buf := make([]byte, 512)
cnt, err := conn.Read(buf)
if err != nil {
fmt.Println("read buf error ")
return
}
fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)
fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

3
examples/zinx_version_ex/ZinxV0.2Test/Server.go

@ -4,9 +4,6 @@ import (
"github.com/aceld/zinx/znet"
)
//Server 模块的测试函数
func main() {

14
examples/zinx_version_ex/ZinxV0.3Test/Client.go

@ -8,14 +8,14 @@ import (
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -23,20 +23,20 @@ func main() {
for {
_, err := conn.Write([]byte("Zinx V0.3"))
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
buf :=make([]byte, 512)
buf := make([]byte, 512)
cnt, err := conn.Read(buf)
if err != nil {
fmt.Println("read buf error ")
return
}
fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)
fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

9
examples/zinx_version_ex/ZinxV0.3Test/Server.go

@ -15,15 +15,16 @@ type PingRouter struct {
func (this *PingRouter) PreHandle(request ziface.IRequest) {
fmt.Println("Call Router PreHandle")
_, err := request.GetConnection().GetTCPConnection().Write([]byte("before ping ....\n"))
if err !=nil {
if err != nil {
fmt.Println("call back ping ping ping error")
}
}
//Test Handle
func (this *PingRouter) Handle(request ziface.IRequest) {
fmt.Println("Call PingRouter Handle")
_, err := request.GetConnection().GetTCPConnection().Write([]byte("ping...ping...ping\n"))
if err !=nil {
if err != nil {
fmt.Println("call back ping ping ping error")
}
}
@ -32,12 +33,12 @@ func (this *PingRouter) Handle(request ziface.IRequest) {
func (this *PingRouter) PostHandle(request ziface.IRequest) {
fmt.Println("Call Router PostHandle")
_, err := request.GetConnection().GetTCPConnection().Write([]byte("After ping .....\n"))
if err !=nil {
if err != nil {
fmt.Println("call back ping ping ping error")
}
}
func main(){
func main() {
//创建一个server句柄
s := znet.NewServer("[zinx V0.3]")

14
examples/zinx_version_ex/ZinxV0.4Test/Client.go

@ -8,14 +8,14 @@ import (
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -23,20 +23,20 @@ func main() {
for {
_, err := conn.Write([]byte("Zinx V0.3"))
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
buf :=make([]byte, 512)
buf := make([]byte, 512)
cnt, err := conn.Read(buf)
if err != nil {
fmt.Println("read buf error ")
return
}
fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)
fmt.Printf(" server call back : %s, cnt = %d\n", buf, cnt)
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

14
examples/zinx_version_ex/ZinxV0.5Test/Client.go

@ -2,22 +2,22 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"time"
"github.com/aceld/zinx/znet"
)
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -26,9 +26,9 @@ func main() {
for {
//发封包message消息
dp := znet.NewDataPack()
msg, _ := dp.Pack(znet.NewMsgPackage(0,[]byte("Zinx V0.5 Client Test Message")))
msg, _ := dp.Pack(znet.NewMsgPackage(0, []byte("Zinx V0.5 Client Test Message")))
_, err := conn.Write(msg)
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
@ -62,6 +62,6 @@ func main() {
fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
}
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

8
examples/zinx_version_ex/ZinxV0.5Test/Server.go

@ -19,10 +19,10 @@ func (this *PingRouter) Handle(request ziface.IRequest) {
//回写数据
/*
_, err := request.GetConnection().GetTCPConnection().Write([]byte("ping...ping...ping\n"))
if err != nil {
fmt.Println("call back ping ping ping error")
}
_, err := request.GetConnection().GetTCPConnection().Write([]byte("ping...ping...ping\n"))
if err != nil {
fmt.Println("call back ping ping ping error")
}
*/
err := request.GetConnection().SendMsg(1, []byte("ping...ping...ping"))
if err != nil {

14
examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/Client0.go

@ -2,22 +2,22 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"time"
"github.com/aceld/zinx/znet"
)
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -26,9 +26,9 @@ func main() {
for {
//发封包message消息
dp := znet.NewDataPack()
msg, _ := dp.Pack(znet.NewMsgPackage(0,[]byte("Zinx V0.6 Client0 Test Message")))
msg, _ := dp.Pack(znet.NewMsgPackage(0, []byte("Zinx V0.6 Client0 Test Message")))
_, err := conn.Write(msg)
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
@ -62,6 +62,6 @@ func main() {
fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
}
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

14
examples/zinx_version_ex/ZinxV0.6Test-V0.7Test/Client1.go

@ -2,22 +2,22 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"time"
"github.com/aceld/zinx/znet"
)
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -26,9 +26,9 @@ func main() {
for {
//发封包message消息
dp := znet.NewDataPack()
msg, _ := dp.Pack(znet.NewMsgPackage(1,[]byte("Zinx V0.6 Client1 Test Message")))
msg, _ := dp.Pack(znet.NewMsgPackage(1, []byte("Zinx V0.6 Client1 Test Message")))
_, err := conn.Write(msg)
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
@ -62,6 +62,6 @@ func main() {
fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
}
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

14
examples/zinx_version_ex/ZinxV0.8Test/Client0.go

@ -2,22 +2,22 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"time"
"github.com/aceld/zinx/znet"
)
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -26,9 +26,9 @@ func main() {
for {
//发封包message消息
dp := znet.NewDataPack()
msg, _ := dp.Pack(znet.NewMsgPackage(0,[]byte("Zinx V0.8 Client0 Test Message")))
msg, _ := dp.Pack(znet.NewMsgPackage(0, []byte("Zinx V0.8 Client0 Test Message")))
_, err := conn.Write(msg)
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
@ -62,6 +62,6 @@ func main() {
fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
}
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

14
examples/zinx_version_ex/ZinxV0.8Test/Client1.go

@ -2,22 +2,22 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"time"
"github.com/aceld/zinx/znet"
)
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -26,9 +26,9 @@ func main() {
for {
//发封包message消息
dp := znet.NewDataPack()
msg, _ := dp.Pack(znet.NewMsgPackage(1,[]byte("Zinx V0.8 Client1 Test Message")))
msg, _ := dp.Pack(znet.NewMsgPackage(1, []byte("Zinx V0.8 Client1 Test Message")))
_, err := conn.Write(msg)
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
@ -62,6 +62,6 @@ func main() {
fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
}
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

14
examples/zinx_version_ex/ZinxV0.9Test/Client0.go

@ -2,22 +2,22 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"time"
"github.com/aceld/zinx/znet"
)
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -26,9 +26,9 @@ func main() {
for {
//发封包message消息
dp := znet.NewDataPack()
msg, _ := dp.Pack(znet.NewMsgPackage(0,[]byte("Zinx V0.8 Client0 Test Message")))
msg, _ := dp.Pack(znet.NewMsgPackage(0, []byte("Zinx V0.8 Client0 Test Message")))
_, err := conn.Write(msg)
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
@ -62,6 +62,6 @@ func main() {
fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
}
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

14
examples/zinx_version_ex/ZinxV0.9Test/Client1.go

@ -2,22 +2,22 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"time"
"github.com/aceld/zinx/znet"
)
/*
模拟客户端
*/
*/
func main() {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
time.Sleep(3 * time.Second)
conn,err := net.Dial("tcp", "127.0.0.1:7777")
conn, err := net.Dial("tcp", "127.0.0.1:7777")
if err != nil {
fmt.Println("client start err, exit!")
return
@ -26,9 +26,9 @@ func main() {
for n := 3; n >= 0; n-- {
//发封包message消息
dp := znet.NewDataPack()
msg, _ := dp.Pack(znet.NewMsgPackage(1,[]byte("Zinx V0.8 Client1 Test Message")))
msg, _ := dp.Pack(znet.NewMsgPackage(1, []byte("Zinx V0.8 Client1 Test Message")))
_, err := conn.Write(msg)
if err !=nil {
if err != nil {
fmt.Println("write error err ", err)
return
}
@ -62,6 +62,6 @@ func main() {
fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
}
time.Sleep(1*time.Second)
time.Sleep(1 * time.Second)
}
}
}

4
examples/zinx_version_ex/datapackDemo/Client.go

@ -2,8 +2,8 @@ package main
import (
"fmt"
"net"
"github.com/aceld/zinx/znet"
"net"
)
func main() {
@ -50,5 +50,3 @@ func main() {
//客户端阻塞
select {}
}

2
examples/zinx_version_ex/datapackDemo/Server.go

@ -2,9 +2,9 @@ package main
import (
"fmt"
"github.com/aceld/zinx/znet"
"io"
"net"
"github.com/aceld/zinx/znet"
)
//只是负责测试datapack拆包,封包功能

2
examples/zinx_version_ex/protoDemo/main.go

@ -2,8 +2,8 @@ package main
import (
"fmt"
"github.com/golang/protobuf/proto"
"github.com/aceld/zinx/examples/zinx_version_ex/protoDemo/pb"
"github.com/golang/protobuf/proto"
)
func main() {

4
utils/globalobj.go

@ -2,10 +2,10 @@ package utils
import (
"encoding/json"
"io/ioutil"
"os"
"github.com/aceld/zinx/ziface"
"github.com/aceld/zinx/zlog"
"io/ioutil"
"os"
)
/*

5
ziface/iconnection.go

@ -24,10 +24,7 @@ type IConnection interface {
//设置链接属性
SetProperty(key string, value interface{})
//获取链接属性
GetProperty(key string)(interface{}, error)
GetProperty(key string) (interface{}, error)
//移除链接属性
RemoveProperty(key string)
}

4
ziface/iconnmanager.go

@ -2,11 +2,11 @@ package ziface
/*
连接管理抽象层
*/
*/
type IConnManager interface {
Add(conn IConnection) //添加链接
Remove(conn IConnection) //删除连接
Get(connID uint32) (IConnection, error) //利用ConnID获取链接
Len() int //获取当前连接
ClearConn() //删除并停止所有链接
ClearConn() //删除并停止所有链接
}

10
ziface/idatapack.go

@ -3,9 +3,9 @@ package ziface
/*
封包数据和拆包数据
直接面向TCP连接中的数据流,为传输数据添加头部信息用于处理TCP粘包问题
*/
type IDataPack interface{
GetHeadLen() uint32 //获取包头长度方法
Pack(msg IMessage)([]byte, error) //封包方法
Unpack([]byte)(IMessage, error) //拆包方法
*/
type IDataPack interface {
GetHeadLen() uint32 //获取包头长度方法
Pack(msg IMessage) ([]byte, error) //封包方法
Unpack([]byte) (IMessage, error) //拆包方法
}

14
ziface/imessage.go

@ -2,13 +2,13 @@ package ziface
/*
将请求的一个消息封装到message中定义抽象层接口
*/
*/
type IMessage interface {
GetDataLen() uint32 //获取消息数据段长度
GetMsgId() uint32 //获取消息ID
GetData() []byte //获取消息内容
GetDataLen() uint32 //获取消息数据段长度
GetMsgId() uint32 //获取消息ID
GetData() []byte //获取消息内容
SetMsgId(uint32) //设计消息ID
SetData([]byte) //设计消息内容
SetDataLen(uint32) //设置消息数据段长度
SetMsgId(uint32) //设计消息ID
SetData([]byte) //设计消息内容
SetDataLen(uint32) //设置消息数据段长度
}

12
ziface/imsghandler.go

@ -2,10 +2,10 @@ package ziface
/*
消息管理抽象层
*/
type IMsgHandle interface{
DoMsgHandler(request IRequest) //马上以非阻塞方式处理消息
AddRouter(msgId uint32, router IRouter) //为消息添加具体的处理逻辑
StartWorkerPool() //启动worker工作池
*/
type IMsgHandle interface {
DoMsgHandler(request IRequest) //马上以非阻塞方式处理消息
AddRouter(msgId uint32, router IRouter) //为消息添加具体的处理逻辑
StartWorkerPool() //启动worker工作池
SendMsgToTaskQueue(request IRequest) //将消息交给TaskQueue,由worker进行处理
}
}

9
ziface/irequest.go

@ -4,9 +4,8 @@ package ziface
IRequest 接口
实际上是把客户端请求的链接信息 请求的数据 包装到了 Request里
*/
type IRequest interface{
GetConnection() IConnection //获取请求连接信息
GetData() []byte //获取请求消息的数据
GetMsgID() uint32 //获取请求的消息ID
type IRequest interface {
GetConnection() IConnection //获取请求连接信息
GetData() []byte //获取请求消息的数据
GetMsgID() uint32 //获取请求的消息ID
}

4
ziface/irouter.go

@ -4,8 +4,8 @@ package ziface
路由接口 这里面路由是 使用框架者给该链接自定的 处理业务方法
路由里的IRequest 则包含用该链接的链接信息和该链接的请求数据信息
*/
type IRouter interface{
type IRouter interface {
PreHandle(request IRequest) //在处理conn业务之前的钩子方法
Handle(request IRequest) //处理conn业务的方法
Handle(request IRequest) //处理conn业务的方法
PostHandle(request IRequest) //处理conn业务之后的钩子方法
}

8
ziface/iserver.go

@ -1,7 +1,7 @@
package ziface
//定义服务器接口
type IServer interface{
type IServer interface {
//启动服务器方法
Start()
//停止服务器方法
@ -13,11 +13,11 @@ type IServer interface{
//得到链接管理
GetConnMgr() IConnManager
//设置该Server的连接创建时Hook函数
SetOnConnStart(func (IConnection))
SetOnConnStart(func(IConnection))
//设置该Server的连接断开时的Hook函数
SetOnConnStop(func (IConnection))
SetOnConnStop(func(IConnection))
//调用连接OnConnStart Hook函数
CallOnConnStart(conn IConnection)
//调用连接OnConnStop Hook函数
CallOnConnStop(conn IConnection)
}
}

2
zinx_app_demo/mmo_game/api/move.go

@ -2,11 +2,11 @@ package api
import (
"fmt"
"github.com/golang/protobuf/proto"
"github.com/aceld/zinx/ziface"
"github.com/aceld/zinx/zinx_app_demo/mmo_game/core"
"github.com/aceld/zinx/zinx_app_demo/mmo_game/pb"
"github.com/aceld/zinx/znet"
"github.com/golang/protobuf/proto"
)
//玩家移动

4
zinx_app_demo/mmo_game/api/world_chat.go

@ -2,11 +2,11 @@ package api
import (
"fmt"
"github.com/golang/protobuf/proto"
"github.com/aceld/zinx/ziface"
"github.com/aceld/zinx/zinx_app_demo/mmo_game/core"
"github.com/aceld/zinx/zinx_app_demo/mmo_game/pb"
"github.com/aceld/zinx/znet"
"github.com/golang/protobuf/proto"
)
//世界聊天 路由业务
@ -35,4 +35,4 @@ func (*WorldChatApi) Handle(request ziface.IRequest) {
//4. 让player对象发起聊天广播请求
player.Talk(msg.Content)
}
}

2
zinx_app_demo/mmo_game/client_AI_robot.go

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"fmt"
"github.com/aceld/zinx/zinx_app_demo/mmo_game/pb"
"github.com/golang/protobuf/proto"
"io"
"math/rand"
@ -11,7 +12,6 @@ import (
"os"
"os/signal"
"time"
"github.com/aceld/zinx/zinx_app_demo/mmo_game/pb"
)
type Message struct {

4
zinx_app_demo/mmo_game/core/aoi.go

@ -89,7 +89,7 @@ func (m *AOIManager) GetSurroundGridsByGid(gID int) (grids []*Grid) {
grids = append(grids, m.grids[gID])
// 根据gID, 得到格子所在的坐标
x, y := gID % m.CntsX, gID / m.CntsX
x, y := gID%m.CntsX, gID/m.CntsX
// 新建一个临时存储周围格子的数组
surroundGid := make([]int, 0)
@ -105,7 +105,7 @@ func (m *AOIManager) GetSurroundGridsByGid(gID int) (grids []*Grid) {
newY := y + dy[i]
if newX >= 0 && newX < m.CntsX && newY >= 0 && newY < m.CntsY {
surroundGid = append(surroundGid, newY * m.CntsX + x)
surroundGid = append(surroundGid, newY*m.CntsX+x)
}
}

6
zinx_app_demo/mmo_game/core/aoi_test.go

@ -6,12 +6,12 @@ import (
)
func TestNewAOIManager(t *testing.T) {
aoiMgr := NewAOIManager(100,300, 4, 200,450, 5)
aoiMgr := NewAOIManager(100, 300, 4, 200, 450, 5)
fmt.Println(aoiMgr)
}
func TestAOIManagerSuroundGridsByGid(t *testing.T) {
aoiMgr := NewAOIManager(0,250, 5, 0,250, 5)
aoiMgr := NewAOIManager(0, 250, 5, 0, 250, 5)
for k, _ := range aoiMgr.grids {
//得到当前格子周边的九宫格
@ -24,4 +24,4 @@ func TestAOIManagerSuroundGridsByGid(t *testing.T) {
}
fmt.Printf("grid ID: %d, surrounding grid IDs are %v\n", k, gIDs)
}
}
}

4
zinx_app_demo/mmo_game/core/player.go

@ -2,12 +2,12 @@ package core
import (
"fmt"
"github.com/aceld/zinx/ziface"
"github.com/aceld/zinx/zinx_app_demo/mmo_game/pb"
"github.com/golang/protobuf/proto"
"math/rand"
"sync"
"time"
"github.com/aceld/zinx/ziface"
"github.com/aceld/zinx/zinx_app_demo/mmo_game/pb"
)
//玩家对象

4
zinx_app_demo/mmo_game/server.go

@ -9,7 +9,7 @@ import (
)
//当客户端建立连接的时候的hook函数
func OnConnecionAdd(conn ziface.IConnection) {
func OnConnecionAdd(conn ziface.IConnection) {
//创建一个玩家
player := core.NewPlayer(conn)
@ -44,7 +44,7 @@ func OnConnectionLost(conn ziface.IConnection) {
player.LostConnection()
}
fmt.Println("====> Player ", pid , " left =====")
fmt.Println("====> Player ", pid, " left =====")
}

2
zlog/stdzlog.go

@ -3,7 +3,7 @@ package zlog
/*
全局默认提供一个Log对外句柄可以直接使用API系列调用
全局日志对象 StdZinxLog
*/
*/
import "os"

27
zlog/zlogger.go

@ -54,21 +54,21 @@ var levels = []string{
type ZinxLogger struct {
//确保多协程读写文件,防止文件内容混乱,做到协程安全
mu sync.Mutex
mu sync.Mutex
//每行log日志的前缀字符串,拥有日志标记
prefix string
//日志标记位
flag int
flag int
//日志输出的文件描述符
out io.Writer
out io.Writer
//输出的缓冲区
buf bytes.Buffer
buf bytes.Buffer
//当前日志绑定的输出文件
file *os.File
file *os.File
//是否打印调试debug信息
debugClose bool
//获取日志文件名和代码上述的runtime.Call 的函数调用层数
calldDepth int
calldDepth int
}
/*
@ -80,7 +80,7 @@ type ZinxLogger struct {
func NewZinxLog(out io.Writer, prefix string, flag int) *ZinxLogger {
//默认 debug打开, calledDepth深度为2,ZinxLogger对象调用日志打印方法最多调用两层到达output函数
zlog := &ZinxLogger{out: out, prefix: prefix, flag: flag, file:nil, debugClose:false, calldDepth:2}
zlog := &ZinxLogger{out: out, prefix: prefix, flag: flag, file: nil, debugClose: false, calldDepth: 2}
//设置log对象 回收资源 析构方法(不设置也可以,go的Gc会自动回收,强迫症没办法)
runtime.SetFinalizer(zlog, CleanZinxLog)
return zlog
@ -88,11 +88,10 @@ func NewZinxLog(out io.Writer, prefix string, flag int) *ZinxLogger {
/*
回收日志处理
*/
func CleanZinxLog(log *ZinxLogger) {
log.closeFile()
}
*/
func CleanZinxLog(log *ZinxLogger) {
log.closeFile()
}
/*
制作当条日志数据的 格式头信息
@ -299,13 +298,12 @@ func (log *ZinxLogger) AddFlag(flag int) {
}
//设置日志的 用户自定义前缀字符串
func (log *ZinxLogger) SetPrefix(prefix string){
func (log *ZinxLogger) SetPrefix(prefix string) {
log.mu.Lock()
defer log.mu.Unlock()
log.prefix = prefix
}
//设置日志文件输出
func (log *ZinxLogger) SetLogFile(fileDir string, fileName string) {
var file *os.File
@ -396,4 +394,3 @@ func itoa(buf *bytes.Buffer, i int, wid int) {
bp++
}
}

6
zlog/zlogger_test.go

@ -10,10 +10,10 @@ func TestStdZLog(t *testing.T) {
Debug("zinx debug content1")
Debug("zinx debug content2")
Debugf(" zinx debug a = %d\n",10)
Debugf(" zinx debug a = %d\n", 10)
//设置log标记位,加上长文件名称 和 微秒 标记
ResetFlags(BitDate|BitLongFile|BitLevel)
ResetFlags(BitDate | BitLongFile | BitLevel)
Info("zinx info content")
//设置日志前缀,主要标记当前日志模块
@ -21,7 +21,7 @@ func TestStdZLog(t *testing.T) {
Error("zinx error content")
//添加标记位
AddFlag(BitShortFile|BitTime)
AddFlag(BitShortFile | BitTime)
Stack(" Zinx Stack! ")
//设置日志写入文件

8
znet/connection.go

@ -3,11 +3,11 @@ package znet
import (
"errors"
"fmt"
"github.com/aceld/zinx/utils"
"github.com/aceld/zinx/ziface"
"io"
"net"
"sync"
"github.com/aceld/zinx/utils"
"github.com/aceld/zinx/ziface"
)
type Connection struct {
@ -25,7 +25,7 @@ type Connection struct {
ExitBuffChan chan bool
//无缓冲管道,用于读、写两个goroutine之间的消息通信
msgChan chan []byte
//有冲管道,用于读、写两个goroutine之间的消息通信
//有冲管道,用于读、写两个goroutine之间的消息通信
msgBuffChan chan []byte
//链接属性
@ -78,8 +78,8 @@ func (c *Connection) StartWriter() {
return
}
} else {
break
fmt.Println("msgBuffChan is Closed")
break
}
case <-c.ExitBuffChan:
return

11
znet/connmanager.go

@ -3,8 +3,8 @@ package znet
import (
"errors"
"fmt"
"sync"
"github.com/aceld/zinx/ziface"
"sync"
)
/*
@ -17,10 +17,10 @@ type ConnManager struct {
/*
创建一个链接管理
*/
*/
func NewConnManager() *ConnManager {
return &ConnManager{
connections:make(map[uint32] ziface.IConnection),
connections: make(map[uint32]ziface.IConnection),
}
}
@ -45,7 +45,7 @@ func (connMgr *ConnManager) Remove(conn ziface.IConnection) {
//删除连接信息
delete(connMgr.connections, conn.GetConnID())
fmt.Println("connection Remove ConnID=",conn.GetConnID(), " successfully: conn num = ", connMgr.Len())
fmt.Println("connection Remove ConnID=", conn.GetConnID(), " successfully: conn num = ", connMgr.Len())
}
//利用ConnID获取链接
@ -77,9 +77,8 @@ func (connMgr *ConnManager) ClearConn() {
//停止
conn.Stop()
//删除
delete(connMgr.connections,connID)
delete(connMgr.connections, connID)
}
fmt.Println("Clear All Connections successfully: conn num = ", connMgr.Len())
}

10
znet/datapack.go

@ -9,7 +9,7 @@ import (
)
//封包拆包类实例,暂时不需要成员
type DataPack struct {}
type DataPack struct{}
//封包拆包实例初始化方法
func NewDataPack() *DataPack {
@ -17,13 +17,13 @@ func NewDataPack() *DataPack {
}
//获取包头长度方法
func(dp *DataPack) GetHeadLen() uint32 {
func (dp *DataPack) GetHeadLen() uint32 {
//Id uint32(4字节) + DataLen uint32(4字节)
return 8
}
//封包方法(压缩数据)
func(dp *DataPack) Pack(msg ziface.IMessage)([]byte, error) {
func (dp *DataPack) Pack(msg ziface.IMessage) ([]byte, error) {
//创建一个存放bytes字节的缓冲
dataBuff := bytes.NewBuffer([]byte{})
@ -39,14 +39,14 @@ func(dp *DataPack) Pack(msg ziface.IMessage)([]byte, error) {
//写data数据
if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetData()); err != nil {
return nil ,err
return nil, err
}
return dataBuff.Bytes(), nil
}
//拆包方法(解压数据)
func(dp *DataPack) Unpack(binaryData []byte)(ziface.IMessage, error) {
func (dp *DataPack) Unpack(binaryData []byte) (ziface.IMessage, error) {
//创建一个从输入二进制数据的ioReader
dataBuff := bytes.NewReader(binaryData)

4
znet/message.go

@ -10,8 +10,8 @@ type Message struct {
func NewMsgPackage(id uint32, data []byte) *Message {
return &Message{
DataLen: uint32(len(data)),
Id: id,
Data: data,
Id: id,
Data: data,
}
}

27
znet/msghandler.go

@ -2,28 +2,28 @@ package znet
import (
"fmt"
"strconv"
"github.com/aceld/zinx/utils"
"github.com/aceld/zinx/ziface"
"strconv"
)
type MsgHandle struct {
Apis map[uint32]ziface.IRouter //存放每个MsgId 所对应的处理方法的map属性
WorkerPoolSize uint32 //业务工作Worker池的数量
TaskQueue []chan ziface.IRequest //Worker负责取任务的消息队列
Apis map[uint32]ziface.IRouter //存放每个MsgId 所对应的处理方法的map属性
WorkerPoolSize uint32 //业务工作Worker池的数量
TaskQueue []chan ziface.IRequest //Worker负责取任务的消息队列
}
func NewMsgHandle() *MsgHandle {
return &MsgHandle{
Apis: make(map[uint32]ziface.IRouter),
WorkerPoolSize:utils.GlobalObject.WorkerPoolSize,
Apis: make(map[uint32]ziface.IRouter),
WorkerPoolSize: utils.GlobalObject.WorkerPoolSize,
//一个worker对应一个queue
TaskQueue:make([]chan ziface.IRequest, utils.GlobalObject.WorkerPoolSize),
TaskQueue: make([]chan ziface.IRequest, utils.GlobalObject.WorkerPoolSize),
}
}
//将消息交给TaskQueue,由worker进行处理
func (mh *MsgHandle)SendMsgToTaskQueue(request ziface.IRequest) {
func (mh *MsgHandle) SendMsgToTaskQueue(request ziface.IRequest) {
//根据ConnID来分配当前的连接应该由哪个worker负责处理
//轮询的平均分配法则
@ -34,7 +34,6 @@ func (mh *MsgHandle)SendMsgToTaskQueue(request ziface.IRequest) {
mh.TaskQueue[workerID] <- request
}
//马上以非阻塞方式处理消息
func (mh *MsgHandle) DoMsgHandler(request ziface.IRequest) {
handler, ok := mh.Apis[request.GetMsgID()]
@ -66,9 +65,9 @@ func (mh *MsgHandle) StartOneWorker(workerID int, taskQueue chan ziface.IRequest
//不断的等待队列中的消息
for {
select {
//有消息则取出队列的Request,并执行绑定的业务方法
case request := <-taskQueue:
mh.DoMsgHandler(request)
//有消息则取出队列的Request,并执行绑定的业务方法
case request := <-taskQueue:
mh.DoMsgHandler(request)
}
}
}
@ -76,11 +75,11 @@ func (mh *MsgHandle) StartOneWorker(workerID int, taskQueue chan ziface.IRequest
//启动worker工作池
func (mh *MsgHandle) StartWorkerPool() {
//遍历需要启动worker的数量,依此启动
for i:= 0; i < int(mh.WorkerPoolSize); i++ {
for i := 0; i < int(mh.WorkerPoolSize); i++ {
//一个worker被启动
//给当前worker对应的任务队列开辟空间
mh.TaskQueue[i] = make(chan ziface.IRequest, utils.GlobalObject.MaxWorkerTaskLen)
//启动当前Worker,阻塞的等待对应的任务队列是否有消息传递进来
go mh.StartOneWorker(i, mh.TaskQueue[i])
}
}
}

10
znet/request.go

@ -4,18 +4,20 @@ import "github.com/aceld/zinx/ziface"
type Request struct {
conn ziface.IConnection //已经和客户端建立好的 链接
msg ziface.IMessage //客户端请求的数据
msg ziface.IMessage //客户端请求的数据
}
//获取请求连接信息
func(r *Request) GetConnection() ziface.IConnection {
func (r *Request) GetConnection() ziface.IConnection {
return r.conn
}
//获取请求消息的数据
func(r *Request) GetData() []byte {
func (r *Request) GetData() []byte {
return r.msg.GetData()
}
//获取请求的消息的ID
func (r *Request) GetMsgID() uint32 {
return r.msg.GetMsgId()
}
}

8
znet/router.go

@ -3,11 +3,11 @@ package znet
import "github.com/aceld/zinx/ziface"
//实现router时,先嵌入这个基类,然后根据需要对这个基类的方法进行重写
type BaseRouter struct {}
type BaseRouter struct{}
//这里之所以BaseRouter的方法都为空,
// 是因为有的Router不希望有PreHandle或PostHandle
// 所以Router全部继承BaseRouter的好处是,不需要实现PreHandle和PostHandle也可以实例化
func (br *BaseRouter)PreHandle(req ziface.IRequest){}
func (br *BaseRouter)Handle(req ziface.IRequest){}
func (br *BaseRouter)PostHandle(req ziface.IRequest){}
func (br *BaseRouter) PreHandle(req ziface.IRequest) {}
func (br *BaseRouter) Handle(req ziface.IRequest) {}
func (br *BaseRouter) PostHandle(req ziface.IRequest) {}

60
znet/server.go

@ -2,12 +2,12 @@ package znet
import (
"fmt"
"net"
"github.com/aceld/zinx/utils"
"github.com/aceld/zinx/ziface"
"net"
)
var zinx_logo = `
var zinxLogo = `
@ -16,9 +16,9 @@ var zinx_logo = `
`
var top_line = `┌───────────────────────────────────────────────────┐`
var border_line = ``
var bottom_line = `└───────────────────────────────────────────────────┘`
var topLine = `┌───────────────────────────────────────────────────┐`
var borderLine = ``
var bottomLine = `└───────────────────────────────────────────────────┘`
//iServer 接口实现,定义一个Server服务类
type Server struct {
@ -35,26 +35,27 @@ type Server struct {
//当前Server的链接管理器
ConnMgr ziface.IConnManager
//该Server的连接创建时Hook函数
OnConnStart func(conn ziface.IConnection)
OnConnStart func(conn ziface.IConnection)
//该Server的连接断开时的Hook函数
OnConnStop func(conn ziface.IConnection)
}
/*
创建一个服务器句柄
*/
func NewServer () ziface.IServer {
s:= &Server {
Name :utils.GlobalObject.Name,
IPVersion:"tcp4",
IP:utils.GlobalObject.Host,
Port:utils.GlobalObject.TcpPort,
*/
func NewServer() ziface.IServer {
s := &Server{
Name: utils.GlobalObject.Name,
IPVersion: "tcp4",
IP: utils.GlobalObject.Host,
Port: utils.GlobalObject.TcpPort,
msgHandler: NewMsgHandle(),
ConnMgr:NewConnManager(),
ConnMgr: NewConnManager(),
}
return s
}
//============== 实现 ziface.IServer 里的全部接口方法 ========
//开启网络服务
@ -74,7 +75,7 @@ func (s *Server) Start() {
}
//2 监听服务器地址
listenner, err:= net.ListenTCP(s.IPVersion, addr)
listener, err := net.ListenTCP(s.IPVersion, addr)
if err != nil {
fmt.Println("listen", s.IPVersion, "err", err)
return
@ -90,7 +91,7 @@ func (s *Server) Start() {
//3 启动server网络连接业务
for {
//3.1 阻塞等待客户端建立连接请求
conn, err := listenner.AcceptTCP()
conn, err := listener.AcceptTCP()
if err != nil {
fmt.Println("Accept err ", err)
continue
@ -105,7 +106,7 @@ func (s *Server) Start() {
//3.3 处理该新连接请求的 业务 方法, 此时应该有 handler 和 conn是绑定的
dealConn := NewConntion(s, conn, cid, s.msgHandler)
cid ++
cid++
//3.4 启动当前链接的处理业务
go dealConn.Start()
@ -115,7 +116,7 @@ func (s *Server) Start() {
//停止服务
func (s *Server) Stop() {
fmt.Println("[STOP] Zinx server , name " , s.Name)
fmt.Println("[STOP] Zinx server , name ", s.Name)
//将其他需要清理的连接信息或者其他信息 也要一并停止或者清理
s.ConnMgr.ClearConn()
@ -128,11 +129,11 @@ func (s *Server) Serve() {
//TODO Server.Serve() 是否在启动服务的时候 还要处理其他的事情呢 可以在这里添加
//阻塞,否则主Go退出, listenner的go将会退出
select{}
select {}
}
//路由功能:给当前服务注册一个路由业务方法,供客户端链接处理使用
func (s *Server)AddRouter(msgId uint32, router ziface.IRouter) {
func (s *Server) AddRouter(msgId uint32, router ziface.IRouter) {
s.msgHandler.AddRouter(msgId, router)
}
@ -142,12 +143,12 @@ func (s *Server) GetConnMgr() ziface.IConnManager {
}
//设置该Server的连接创建时Hook函数
func (s *Server) SetOnConnStart(hookFunc func (ziface.IConnection)) {
func (s *Server) SetOnConnStart(hookFunc func(ziface.IConnection)) {
s.OnConnStart = hookFunc
}
//设置该Server的连接断开时的Hook函数
func (s *Server) SetOnConnStop(hookFunc func (ziface.IConnection)) {
func (s *Server) SetOnConnStop(hookFunc func(ziface.IConnection)) {
s.OnConnStop = hookFunc
}
@ -168,16 +169,13 @@ func (s *Server) CallOnConnStop(conn ziface.IConnection) {
}
func init() {
fmt.Println(zinx_logo)
fmt.Println(top_line)
fmt.Println(fmt.Sprintf("%s [Github] https://github.com/aceld %s", border_line, border_line))
fmt.Println(fmt.Sprintf("%s [tutorial] https://www.jianshu.com/p/23d07c0a28e5 %s", border_line, border_line))
fmt.Println(bottom_line)
fmt.Println(zinxLogo)
fmt.Println(topLine)
fmt.Println(fmt.Sprintf("%s [Github] https://github.com/aceld %s", borderLine, borderLine))
fmt.Println(fmt.Sprintf("%s [tutorial] https://www.jianshu.com/p/23d07c0a28e5 %s", borderLine, borderLine))
fmt.Println(bottomLine)
fmt.Printf("[Zinx] Version: %s, MaxConn: %d, MaxPacketSize: %d\n",
utils.GlobalObject.Version,
utils.GlobalObject.MaxConn,
utils.GlobalObject.MaxPacketSize)
}

40
znet/server_test.go

@ -15,7 +15,7 @@ import (
/*
模拟客户端
*/
func ClientTest() {
func ClientTest(i uint32) {
fmt.Println("Client Test ... start")
//3秒之后发起测试请求,给服务端开启服务的机会
@ -29,7 +29,7 @@ func ClientTest() {
for {
dp := NewDataPack()
msg, _ := dp.Pack(NewMsgPackage(1, []byte("client test message")))
msg, _ := dp.Pack(NewMsgPackage(i, []byte("client test message")))
_, err := conn.Write(msg)
if err != nil {
fmt.Println("client write err: ", err)
@ -109,14 +109,48 @@ func (this *PingRouter) PostHandle(request ziface.IRequest) {
}
}
type HelloRouter struct {
BaseRouter
}
func (this *HelloRouter) Handle(request ziface.IRequest) {
fmt.Println("call helloRouter Handle")
fmt.Printf("receive from client msgId=%d, data=%s\n", request.GetMsgID(), string(request.GetData()))
err := request.GetConnection().SendMsg(2, []byte("hello zix hello Router"))
if err != nil {
fmt.Println(err)
}
}
func DoConnectionBegin(conn ziface.IConnection) {
fmt.Println("DoConnectionBegin is Called ... ")
err := conn.SendMsg(2, []byte("DoConnection BEGIN..."))
if err != nil {
fmt.Println(err)
}
}
//连接断开的时候执行
func DoConnectionLost(conn ziface.IConnection) {
fmt.Println("DoConnectionLost is Called ... ")
}
func TestServer(t *testing.T) {
//创建一个server句柄
s := NewServer()
//注册链接hook回调函数
s.SetOnConnStart(DoConnectionBegin)
s.SetOnConnStop(DoConnectionLost)
// 多路由
s.AddRouter(1, &PingRouter{})
s.AddRouter(2, &HelloRouter{})
// 客户端测试
go ClientTest()
go ClientTest(1)
go ClientTest(2)
//2 开启服务
go s.Serve()

12
ztimer/delayfunc.go

@ -2,7 +2,7 @@
* @Author: Aceld
* @Date: 2019/4/30 11:57
* @Mail: danbing.at@gmail.com
*/
*/
package ztimer
import (
@ -26,8 +26,8 @@ type DelayFunc struct {
*/
func NewDelayFunc(f func(v ...interface{}), args []interface{}) *DelayFunc {
return &DelayFunc{
f:f,
args:args,
f: f,
args: args,
}
}
@ -36,11 +36,9 @@ func (df *DelayFunc) String() string {
return fmt.Sprintf("{DelayFun:%s, args:%v}", reflect.TypeOf(df.f).Name(), df.args)
}
/*
执行延迟函数---如果执行失败抛出异常
*/
*/
func (df *DelayFunc) Call() {
defer func() {
if err := recover(); err != nil {
@ -50,4 +48,4 @@ func (df *DelayFunc) Call() {
//调用定时器超时函数
df.f(df.args...)
}
}

4
ztimer/delayfunc_test.go

@ -4,7 +4,7 @@
* @Mail: danbing.at@gmail.com
*
* 针对 delayFunc.go 做单元测试主要测试延迟函数结构体是否正常使用
*/
*/
package ztimer
import (
@ -13,7 +13,7 @@ import (
)
func SayHello(message ...interface{}) {
fmt.Println(message[0].(string), " ",message[1].(string))
fmt.Println(message[0].(string), " ", message[1].(string))
}
func TestDelayfunc(t *testing.T) {

16
ztimer/timer.go

@ -10,17 +10,17 @@ import (
)
const (
HOUR_NAME = "HOUR"
HOUR_INTERVAL = 60*60*1e3 //ms为精度
HOUR_SCALES = 12
HOUR_NAME = "HOUR"
HOUR_INTERVAL = 60 * 60 * 1e3 //ms为精度
HOUR_SCALES = 12
MINUTE_NAME = "MINUTE"
MINUTE_NAME = "MINUTE"
MINUTE_INTERVAL = 60 * 1e3
MINUTE_SCALES = 60
MINUTE_SCALES = 60
SECOND_NAME = "SECOND"
SECOND_NAME = "SECOND"
SECOND_INTERVAL = 1e3
SECOND_SCALES = 60
SECOND_SCALES = 60
TIMERS_MAX_CAP = 2048 //每个时间轮刻度挂载定时器的最大个数
)
@ -33,7 +33,7 @@ const (
time.Microsecond(微秒) = time.Nanosecond * 1e3
time.Now().UnixNano() ==> time.Nanosecond (纳秒)
*/
*/
/*
定时器实现

11
ztimer/timer_test.go

@ -4,7 +4,7 @@
* @Mail: danbing.at@gmail.com
*
* 针对timer.go做单元测试主要测试定时器相关接口 依赖模块delayFunc.go
*/
*/
package ztimer
import (
@ -20,13 +20,12 @@ func myFunc(v ...interface{}) {
func TestTimer(t *testing.T) {
for i:=0; i < 5;i ++ {
for i := 0; i < 5; i++ {
go func(i int) {
NewTimerAfter(NewDelayFunc(myFunc,[]interface{}{i, 2*i}), time.Duration(2*i)*time.Second).Run()
NewTimerAfter(NewDelayFunc(myFunc, []interface{}{i, 2 * i}), time.Duration(2*i)*time.Second).Run()
}(i)
}
//主进程等待其他go,由于Run()方法是用一个新的go承载延迟方法,这里不能用waitGroup
time.Sleep(1*time.Minute)
}
time.Sleep(1 * time.Minute)
}

19
ztimer/timerscheduler.go

@ -5,14 +5,14 @@
*
* 时间轮调度器
* 依赖模块delayfunc.go timer.go timewheel.go
*/
*/
package ztimer
import (
"github.com/aceld/zinx/zlog"
"math"
"sync"
"time"
"github.com/aceld/zinx/zlog"
)
const (
@ -57,13 +57,13 @@ func NewTimerScheduler() *TimerScheduler {
hour_tw.Run()
return &TimerScheduler{
tw:hour_tw,
triggerChan:make(chan *DelayFunc, MAX_CHAN_BUFF),
tw: hour_tw,
triggerChan: make(chan *DelayFunc, MAX_CHAN_BUFF),
}
}
//创建一个定点Timer 并将Timer添加到分层时间轮中, 返回Timer的tid
func (this *TimerScheduler) CreateTimerAt(df *DelayFunc, unixNano int64)(uint32, error) {
func (this *TimerScheduler) CreateTimerAt(df *DelayFunc, unixNano int64) (uint32, error) {
this.Lock()
defer this.Unlock()
@ -72,7 +72,7 @@ func (this *TimerScheduler) CreateTimerAt(df *DelayFunc, unixNano int64)(uint32,
}
//创建一个延迟Timer 并将Timer添加到分层时间轮中, 返回Timer的tid
func (this *TimerScheduler) CreateTimerAfter(df *DelayFunc, duration time.Duration)(uint32, error) {
func (this *TimerScheduler) CreateTimerAfter(df *DelayFunc, duration time.Duration) (uint32, error) {
this.Lock()
defer this.Unlock()
@ -81,7 +81,7 @@ func (this *TimerScheduler) CreateTimerAfter(df *DelayFunc, duration time.Durati
}
//删除timer
func(this *TimerScheduler) CancelTimer(tid uint32) {
func (this *TimerScheduler) CancelTimer(tid uint32) {
this.Lock()
this.Unlock()
@ -110,14 +110,13 @@ func (this *TimerScheduler) Start() {
this.triggerChan <- timer.delayFunc
}
time.Sleep(MAX_TIME_DELAY/2 * time.Millisecond)
time.Sleep(MAX_TIME_DELAY / 2 * time.Millisecond)
}
}()
}
//时间轮定时器 自动调度
func NewAutoExecTimerScheduler() *TimerScheduler{
func NewAutoExecTimerScheduler() *TimerScheduler {
//创建一个调度器
autoExecScheduler := NewTimerScheduler()
//启动调度器

24
ztimer/timerscheduler_test.go

@ -4,18 +4,18 @@
* @Mail: danbing.at@gmail.com
*
* 时间轮定时器调度器单元测试
*/
*/
package ztimer
import (
"fmt"
"github.com/aceld/zinx/zlog"
"testing"
"time"
"github.com/aceld/zinx/zlog"
)
//触发函数
func foo(args ...interface{}){
func foo(args ...interface{}) {
fmt.Printf("I am No. %d function, delay %d ms\n", args[0].(int), args[1].(int))
}
@ -25,9 +25,9 @@ func TestNewTimerScheduler(t *testing.T) {
timerScheduler.Start()
//在scheduler中添加timer
for i := 1; i < 2000; i ++ {
f := NewDelayFunc(foo, []interface{}{i, i*3})
tid, err := timerScheduler.CreateTimerAfter(f, time.Duration(3*i) * time.Millisecond)
for i := 1; i < 2000; i++ {
f := NewDelayFunc(foo, []interface{}{i, i * 3})
tid, err := timerScheduler.CreateTimerAfter(f, time.Duration(3*i)*time.Millisecond)
if err != nil {
zlog.Error("create timer error", tid, err)
break
@ -43,7 +43,7 @@ func TestNewTimerScheduler(t *testing.T) {
}()
//阻塞等待
select{}
select {}
}
//采用自动调度器运转时间轮
@ -51,9 +51,9 @@ func TestNewAutoExecTimerScheduler(t *testing.T) {
autoTS := NewAutoExecTimerScheduler()
//给调度器添加Timer
for i := 0; i < 2000; i ++ {
f := NewDelayFunc(foo, []interface{}{i, i*3})
tid, err := autoTS.CreateTimerAfter(f, time.Duration(3*i) * time.Millisecond)
for i := 0; i < 2000; i++ {
f := NewDelayFunc(foo, []interface{}{i, i * 3})
tid, err := autoTS.CreateTimerAfter(f, time.Duration(3*i)*time.Millisecond)
if err != nil {
zlog.Error("create timer error", tid, err)
break
@ -61,7 +61,5 @@ func TestNewAutoExecTimerScheduler(t *testing.T) {
}
//阻塞等待
select{}
select {}
}

12
ztimer/timewheel.go

@ -8,9 +8,9 @@ package ztimer
import (
"errors"
"fmt"
"github.com/aceld/zinx/zlog"
"sync"
"time"
"github.com/aceld/zinx/zlog"
)
/*
@ -110,7 +110,7 @@ func (tw *TimeWheel) addTimer(tid uint32, t *Timer, forceNext bool) error {
//因为这是底层时间轮,该定时器在转动的时候,如果没有被调度者取走的话,该定时器将不会再被发现
//因为时间轮刻度已经过去,如果不强制把该定时器Timer移至下时刻,就永远不会被取走并触发调用
//所以这里强制将timer移至下个刻度的集合中,等待调用者在下次轮转之前取走该定时器
tw.timerQueue[(tw.curIndex+1) % tw.scales][tid] = t
tw.timerQueue[(tw.curIndex+1)%tw.scales][tid] = t
} else {
//如果手动添加定时器,那么直接将timer添加到对应底层时间轮的当前刻度集合中
tw.timerQueue[tw.curIndex][tid] = t
@ -153,7 +153,7 @@ func (tw *TimeWheel) RemoveTimer(tid uint32) {
*/
func (tw *TimeWheel) AddTimeWheel(next *TimeWheel) {
tw.nextTimeWheel = next
zlog.Info("Add timerWhell[", tw.name,"]'s next [", next.name,"] is succ!")
zlog.Info("Add timerWhell[", tw.name, "]'s next [", next.name, "] is succ!")
}
/*
@ -175,14 +175,14 @@ func (tw *TimeWheel) run() {
}
//取出下一个刻度 挂载的全部定时器 进行重新添加 (为了安全起见,待考慮)
nextTimers := tw.timerQueue[(tw.curIndex+1) % tw.scales]
tw.timerQueue[(tw.curIndex+1) % tw.scales] = make(map[uint32]*Timer, tw.maxCap)
nextTimers := tw.timerQueue[(tw.curIndex+1)%tw.scales]
tw.timerQueue[(tw.curIndex+1)%tw.scales] = make(map[uint32]*Timer, tw.maxCap)
for tid, timer := range nextTimers {
tw.addTimer(tid, timer, true)
}
//当前刻度指针 走一格
tw.curIndex = (tw.curIndex+1) % tw.scales
tw.curIndex = (tw.curIndex + 1) % tw.scales
tw.Unlock()
}

17
ztimer/timewheel_test.go

@ -5,7 +5,7 @@
*
* 针对 timer_wheel.go 时间轮api 做单元测试, 主要测试时间轮运转功能
* 依赖模块 delayFunc.go timer.go
*/
*/
package ztimer
import (
@ -30,31 +30,30 @@ func TestTimerWheel(t *testing.T) {
fmt.Println("init timewheels done!")
//===== > 以上为初始化分层时间轮 <====
//给时间轮添加定时器
timer1 := NewTimerAfter(NewDelayFunc(myFunc, []interface{}{1,10}), 10 * time.Second)
timer1 := NewTimerAfter(NewDelayFunc(myFunc, []interface{}{1, 10}), 10*time.Second)
_ = hour_tw.AddTimer(1, timer1)
fmt.Println("add timer 1 done!")
//给时间轮添加定时器
timer2 := NewTimerAfter(NewDelayFunc(myFunc, []interface{}{2,20}), 20 * time.Second)
timer2 := NewTimerAfter(NewDelayFunc(myFunc, []interface{}{2, 20}), 20*time.Second)
_ = hour_tw.AddTimer(2, timer2)
fmt.Println("add timer 2 done!")
//给时间轮添加定时器
timer3 := NewTimerAfter(NewDelayFunc(myFunc, []interface{}{3,30}), 30 * time.Second)
timer3 := NewTimerAfter(NewDelayFunc(myFunc, []interface{}{3, 30}), 30*time.Second)
_ = hour_tw.AddTimer(3, timer3)
fmt.Println("add timer 3 done!")
//给时间轮添加定时器
timer4 := NewTimerAfter(NewDelayFunc(myFunc, []interface{}{4,40}), 40 * time.Second)
timer4 := NewTimerAfter(NewDelayFunc(myFunc, []interface{}{4, 40}), 40*time.Second)
_ = hour_tw.AddTimer(4, timer4)
fmt.Println("add timer 4 done!")
//给时间轮添加定时器
timer5 := NewTimerAfter(NewDelayFunc(myFunc, []interface{}{5,50}), 50 * time.Second)
timer5 := NewTimerAfter(NewDelayFunc(myFunc, []interface{}{5, 50}), 50*time.Second)
_ = hour_tw.AddTimer(5, timer5)
fmt.Println("add timer 5 done!")
@ -71,7 +70,7 @@ func TestTimerWheel(t *testing.T) {
fmt.Println("tick...", n)
//取出近1ms的超时定时器有哪些
timers := hour_tw.GetTimerWithIn(1000 *time.Millisecond)
timers := hour_tw.GetTimerWithIn(1000 * time.Millisecond)
for _, timer := range timers {
//调用定时器方法
timer.delayFunc.Call()
@ -83,5 +82,5 @@ func TestTimerWheel(t *testing.T) {
}()
//主进程等待其他go,由于Run()方法是用一个新的go承载延迟方法,这里不能用waitGroup
time.Sleep(10*time.Minute)
time.Sleep(10 * time.Minute)
}
Loading…
Cancel
Save