<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Zinx基于 Go 的輕量級(jí)并發(fā)服務(wù)器框架

          聯(lián)合創(chuàng)作 · 2023-09-29 13:29

          Zinx 是一個(gè)基于Golang的輕量級(jí)并發(fā)服務(wù)器框架

          開發(fā)人員

          -   劉丹冰(@aceld)
          -   張超(@zhngcho)


          一、寫在前面

          我們?yōu)槭裁匆鯶inx,Golang目前在服務(wù)器的應(yīng)用框架很多,但是應(yīng)用在游戲領(lǐng)域或者其他長(zhǎng)鏈接的領(lǐng)域的輕量級(jí)企業(yè)框架甚少。

          設(shè)計(jì)Zinx的目的是我們可以通過Zinx框架來(lái)了解基于Golang編寫一個(gè)TCP服務(wù)器的整體輪廓,讓更多的Golang愛好者能深入淺出的去學(xué)習(xí)和認(rèn)識(shí)這個(gè)領(lǐng)域。

          Zinx框架的項(xiàng)目制作采用編碼和學(xué)習(xí)教程同步進(jìn)行,將開發(fā)的全部遞進(jìn)和迭代思維帶入教程中,而不是一下子給大家一個(gè)非常完整的框架去學(xué)習(xí),讓很多人一頭霧水,不知道該如何學(xué)起。

          教程會(huì)一個(gè)版本一個(gè)版本迭代,每個(gè)版本的添加功能都是微小的,讓一個(gè)服務(wù)框架小白,循序漸進(jìn)的曲線方式了解服務(wù)器框架的領(lǐng)域。

          當(dāng)然,最后希望Zinx會(huì)有更多的人加入,給我們提出寶貴的意見,讓Zinx成為真正的解決企業(yè)的服務(wù)器框架!在此感謝您的關(guān)注!

          二、初探Zinx架構(gòu)

          三、Zinx詳細(xì)教程(代碼教程同步更新)

          《Zinx框架教程-基于Golang的輕量級(jí)并發(fā)服務(wù)器》

          四、Zinx開發(fā)API文檔

          快速開始

          server


          基于Zinx框架開發(fā)的服務(wù)器應(yīng)用,主函數(shù)步驟比較精簡(jiǎn),最多主需要3步即可。
          1. 創(chuàng)建server句柄
          2. 配置自定義路由及業(yè)務(wù)
          3. 啟動(dòng)服務(wù)

          func main() {
              //1 創(chuàng)建一個(gè)server句柄
              s := znet.NewServer()
          
              //2 配置路由
              s.AddRouter(0, &PingRouter{})
          
              //3 開啟服務(wù)
              s.Serve()
          }

          其中自定義路由及業(yè)務(wù)配置方式如下:

          import (
              "fmt"
              "zinx/ziface"
              "zinx/znet"
          )
          
          //ping test 自定義路由
          type PingRouter struct {
              znet.BaseRouter
          }
          
          //Ping Handle
          func (this *PingRouter) Handle(request ziface.IRequest) {
              //先讀取客戶端的數(shù)據(jù)
              fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
          
              //再回寫ping...ping...ping
              err := request.GetConnection().SendBuffMsg(0, []byte("ping...ping...ping"))
              if err != nil {
                  fmt.Println(err)
              }
          }

          client

          Zinx的消息處理采用,`[MsgLength]|[MsgID]|[Data]`的封包格式
           

          package main
          
          import (
              "fmt"
              "io"
              "net"
              "time"
              "zinx/znet"
          )
          
          /*
              模擬客戶端
           */
          func main() {
          
              fmt.Println("Client Test ... start")
              //3秒之后發(fā)起測(cè)試請(qǐng)求,給服務(wù)端開啟服務(wù)的機(jī)會(huì)
              time.Sleep(3 * time.Second)
          
              conn,err := net.Dial("tcp", "127.0.0.1:7777")
              if err != nil {
                  fmt.Println("client start err, exit!")
                  return
              }
          
              for n := 3; n >= 0; n-- {
                  //發(fā)封包message消息
                  dp := znet.NewDataPack()
                  msg, _ := dp.Pack(znet.NewMsgPackage(0,[]byte("Zinx Client Test Message")))
                  _, err := conn.Write(msg)
                  if err !=nil {
                      fmt.Println("write error err ", err)
                      return
                  }
          
                  //先讀出流中的head部分
                  headData := make([]byte, dp.GetHeadLen())
                  _, err = io.ReadFull(conn, headData) //ReadFull 會(huì)把msg填充滿為止
                  if err != nil {
                      fmt.Println("read head error")
                      break
                  }
                  //將headData字節(jié)流 拆包到msg中
                  msgHead, err := dp.Unpack(headData)
                  if err != nil {
                      fmt.Println("server unpack err:", err)
                      return
                  }
          
                  if msgHead.GetDataLen() > 0 {
                      //msg 是有data數(shù)據(jù)的,需要再次讀取data數(shù)據(jù)
                      msg := msgHead.(*znet.Message)
                      msg.Data = make([]byte, msg.GetDataLen())
          
                      //根據(jù)dataLen從io中讀取字節(jié)流
                      _, err := io.ReadFull(conn, msg.Data)
                      if err != nil {
                          fmt.Println("server unpack data err:", err)
                          return
                      }
          
                      fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
                  }
          
                  time.Sleep(1*time.Second)
              }
          }

          Zinx配置文件

          {
            "Name":"Zinx Game", 
            "Host":"0.0.0.0",
            "TcpPort":8999,
            "MaxConn":3000,
            "WorkerPoolSize":10
          }

          `Name`:服務(wù)器應(yīng)用名稱

          `Host`:服務(wù)器IP

          `TcpPort`:服務(wù)器監(jiān)聽端口

          `MaxConn`:允許的客戶端鏈接最大數(shù)量

          `WorkerPoolSize`:工作任務(wù)池最大工作Goroutine數(shù)量


          I.服務(wù)器模塊Server

            func NewServer () ziface.IServer 

          創(chuàng)建一個(gè)Zinx服務(wù)器句柄,該句柄作為當(dāng)前服務(wù)器應(yīng)用程序的主樞紐,包括如下功能:

          1)開啟服務(wù)

           func (s *Server) Start()

          2)停止服務(wù)

            func (s *Server) Stop()

          3)運(yùn)行服務(wù)

           func (s *Server) Serve()

          4)注冊(cè)路由

          func (s *Server) AddRouter (msgId uint32, router ziface.IRouter) 

          5)注冊(cè)鏈接創(chuàng)建Hook函數(shù)

          func (s *Server) SetOnConnStart(hookFunc func (ziface.IConnection))

          6)注冊(cè)鏈接銷毀Hook函數(shù)

          func (s *Server) SetOnConnStop(hookFunc func (ziface.IConnection))

          II.路由模塊

          //實(shí)現(xiàn)router時(shí),先嵌入這個(gè)基類,然后根據(jù)需要對(duì)這個(gè)基類的方法進(jìn)行重寫
          type BaseRouter struct {}
          
          //這里之所以BaseRouter的方法都為空,
          // 是因?yàn)橛械腞outer不希望有PreHandle或PostHandle
          // 所以Router全部繼承BaseRouter的好處是,不需要實(shí)現(xiàn)PreHandle和PostHandle也可以實(shí)例化
          func (br *BaseRouter)PreHandle(req ziface.IRequest){}
          func (br *BaseRouter)Handle(req ziface.IRequest){}
          func (br *BaseRouter)PostHandle(req ziface.IRequest){}


          III.鏈接模塊


          1)獲取原始的socket TCPConn

            func (c *Connection) GetTCPConnection() *net.TCPConn 

          2)獲取鏈接ID

            func (c *Connection) GetConnID() uint32 

          3)獲取遠(yuǎn)程客戶端地址信息

          func (c *Connection) RemoteAddr() net.Addr 

          4)發(fā)送消息

            func (c *Connection) SendMsg(msgId uint32, data []byte) error 
            func (c *Connection) SendBuffMsg(msgId uint32, data []byte) error

          5)鏈接屬性

          //設(shè)置鏈接屬性
          func (c *Connection) SetProperty(key string, value interface{})
          
          //獲取鏈接屬性
          func (c *Connection) GetProperty(key string) (interface{}, error)
          
          //移除鏈接屬性
          func (c *Connection) RemoveProperty(key string) 


                                                                      

          mail:    [email protected]
          github: https://github.com/aceld
          原創(chuàng)書籍gitbook:  http://legacy.gitbook.com/@aceld

          瀏覽 25
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费三级成人爱做片 | 男女瑟瑟视频 | 国产一级性在线观看 | 69.成人免费电影 | 天天好逼网好逼天天有 |