Zinx Framework
repository·master·Indexed 27 days ago
https://github.com/aceld/zinxA lightweight, concurrent TCP server framework for Golang (version 1.17+) optimized for long-lived connection scenarios such as gaming servers and message forwarding. It provides a simple structure for implementing servers and clients, featuring a worker pool, JSON-based configuration, and routing mechanisms. The framework includes a case study for an MMO game server with AOI-based broadcasting and global chat.
What's inside zinx
- Zinx is a lightweight concurrent server framework based on Golang. It is designed for scenarios requiring high concurrency and long connections, such as message relaying for backend modules, long-connection game servers, and message processing plugins within Web frameworks. The framework aims to provide a simple code structure that allows developers to understand the internal details of a TCP server and easily perform secondary development (DIY) for specific enterprise needs.
MMO Game Case Study Overview
masterThe
zinx_app_demo/mmo_gamerepository serves as a practical case study for building a server-side application using the Zinx framework. It implements an MMO (Massively Multiplayer Online) game server featuring essential modules such as:- AOI (Area Of Interest) based broadcasting: Efficiently managing message distribution based on player proximity.
- Global Chat: A system for world-wide communication.
The demo is designed to work with a Unity3D client, which can be found at the following repository:
https://github.com/aceld/mmo_game_clientMMO Game Server Example Overview
masterThe MMO Game case study demonstrates how to build a Massively Multiplayer Online (MMO) game server using the Zinx framework. It includes core game modules such as AOI (Area of Interest) based broadcasting and world chat. This example is designed to work with a Unity3D client.
MMO Game Client Source Code (for learning purposes):
https://github.com/aceld/mmo_game_clientQuickstart: Create a Zinx Server
masterTo create a server, use
znet.NewServer()to initialize the service,AddRouterto map specific message IDs to router implementations (which embedznet.BaseRouter), andServe()to start the server. The router'sHandlemethod receives anziface.IRequestcontaining the message ID and data.package main import ( "fmt" "github.com/aceld/zinx/ziface" "github.com/aceld/zinx/znet" ) // PingRouter handles messages with MsgId=1 type PingRouter struct { znet.BaseRouter } // Handle is the routing method for MsgId=1 func (r *PingRouter) Handle(request ziface.IRequest) { // Read client data fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData())) } func main() { // 1. Create a server service s := znet.NewServer() // 2. Configure router s.AddRouter(1, &PingRouter{}) // 3. Start service s.Serve() }Quickstart: Create a Zinx Client
masterTo create a client, use
znet.NewClient(host, port). You can useSetOnConnStartto register a hook function that executes when a connection is successfully established. Useconn.SendMsg(msgId, data)to send messages to the server.package main import ( "fmt" "github.com/aceld/zinx/ziface" "github.com/aceld/zinx/znet" "time" ) // Custom business logic for the client func pingLoop(conn ziface.IConnection) { for { err := conn.SendMsg(1, []byte("Ping...Ping...Ping...[FromClient]")) if err != nil { fmt.Println(err) break } time.Sleep(1 * time.Second) } } // Hook function called when connection is established func onClientStart(conn ziface.IConnection) { fmt.Println("onClientStart is Called ... ") go pingLoop(conn) } func main() { // Create Client client := znet.NewClient("127.0.0.1", 8999) // Set hook function for successful connection client.SetOnConnStart(onClientStart) // Start client client.Start() // Prevent process from exiting select {} }QuickStart: Implement a Zinx Client
masterTo create a Zinx client:
- Use
znet.NewClient(host, port)to initialize the client. - Use
client.SetOnConnStart(hookFunc)to define a callback function that executes when a connection is successfully established. - Call
client.Start()to begin the connection process. - Use
conn.SendMsg(msgId, data)within your business logic to send messages to the server.
package main import ( "fmt" "github.com/aceld/zinx/ziface" "github.com/aceld/zinx/znet" "time" ) //Client custom business func pingLoop(conn ziface.IConnection) { for { err := conn.SendMsg(1, []byte("Ping...Ping...Ping...[FromClient]")) if err != nil { fmt.Println(err) break } time.Sleep(1 * time.Second) } } //Executed when a connection is created func onClientStart(conn ziface.IConnection) { fmt.Println("onClientStart is Called ... ") go pingLoop(conn) } func main() { //Create a client client client := znet.NewClient("127.0.0.1", 8999) //Set the hook function after the link is successfully established client.SetOnConnStart(onClientStart) //start the client client.Start() //Prevent the process from exiting, waiting for an interrupt signal select {} }- Use
QuickStart: Implement a Zinx Server
masterTo create a Zinx server, follow these steps:
- Define a router struct that embeds
znet.BaseRouter. - Implement the
Handle(request ziface.IRequest)method to process incoming messages. - In
main(), useznet.NewServer()to create the service. - Register your router using
s.AddRouter(msgId, routerInstance). - Start the service with
s.Serve().
package main import ( "fmt" "github.com/aceld/zinx/ziface" "github.com/aceld/zinx/znet" ) // PingRouter MsgId=1 type PingRouter struct { znet.BaseRouter } //Ping Handle MsgId=1 func (r *PingRouter) Handle(request ziface.IRequest) { //read client data fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData())) } func main() { //1 Create a server service s := znet.NewServer() //2 configure routing s.AddRouter(1, &PingRouter{}) //3 start service s.Serve() }- Define a router struct that embeds
Access Zinx Tutorials and Documentation
masterTo learn how to use the Zinx framework for building services, you can access the following resources:
Documentation
- Zinx Wiki (English): https://github.com/aceld/zinx/wiki
- Zinx Documentation (Chinese): https://www.yuque.com/aceld/tsgooa/sbvzgczh3hqz8q3l
Online Tutorials
- Dev.to (English): Building basic services with Zinx framework
- Yuque (Chinese): 《Golang轻量级并发服务器框架zinx》
Video Tutorials
- Bilibili: Search for Zinx tutorials on Bilibili
- YouTube: Zinx Framework Playlist
Access Zinx Documentation and Tutorials
masterZinx provides several resources for developers to learn and implement the framework:
Documentation
- English Wiki: Zinx Wiki
- Chinese Documentation: YuQue Zinx Docs
Learning Tutorials
- Text-based Tutorials:
- Video Tutorials:
Install Zinx
masterTo use Zinx in your Go project, download the source using
go get. Note that Zinx requires Golang Version 1.17+.$go get github.com/aceld/zinxZinx Learning Resources and Tutorials
masterTo learn how to use the Zinx framework, you can access various documentation and tutorial formats:
Documentation
- English Wiki: Zinx Wiki
- Chinese Documentation: Yuque Zinx Docs
Text Tutorials
Video Tutorials
- Bilibili: Zinx Video Tutorial
- Douyin: Zinx Video Tutorial
- YouTube: Zinx Video Tutorial
Configure Zinx via JSON
masterZinx can be configured using a JSON file. The following keys are available:
Name: Application name.Host: Server IP address.TCPPort: Port the server listens on.MaxConn: Maximum number of allowed client connections.WorkerPoolSize: Maximum number of Goroutines in the worker task pool.LogDir: Directory for log files.LogFile: Name of the log file (if omitted, logs are printed to Stderr).LogSaveDays: Number of days to retain logs.LogCons: Whether to output logs to the console.LogIsolationLevel: Log isolation level (0: All, 1: Hide debug, 2: Hide debug/info, 3: Hide debug/info/warn).
{ "Name":"zinx v-0.10 demoApp", "Host":"0.0.0.0", "TCPPort":9090, "MaxConn":3, "WorkerPoolSize":10, "LogDir": "./mylog", "LogFile":"app.log", "LogSaveDays":15, "LogCons": true, "LogIsolationLevel":0 }