【Zinx第一章-引言】Golang輕量級(jí)并發(fā)服務(wù)器框架

Zinx源代碼

github
https://github.com/aceld/zinx
gitee碼云
https://gitee.com/Aceld/zinx


在線開發(fā)教程

【B站】
zinx視頻教程-Golang輕量級(jí)TCP服務(wù)器框架-適合自學(xué)者

【YouTube】
zinx開發(fā)YouTube中國(guó)版

微信端文檔

技術(shù)資源分享.jpg

【Zinx教程目錄】
完整教程電子版(在線高清)-下載
Zinx框架視頻教程(框架篇)(完整版下載)鏈接在下面正文
Zinx框架視頻教程(應(yīng)用篇)(完整版下載)鏈接在下面正文
Zinx開發(fā)API文檔
Zinx第一章-引言
Zinx第二章-初識(shí)Zinx框架
Zinx第三章-基礎(chǔ)路由模塊
Zinx第四章-全局配置
Zinx第五章-消息封裝
Zinx第六章-多路由模式
Zinx第七章-讀寫分離模型
Zinx第八章-消息隊(duì)列及多任務(wù)
Zinx第九章-鏈接管理
Zinx第十章-連接屬性設(shè)置


【Zinx應(yīng)用案例-MMO多人在線游戲】
(1)案例介紹
(2)AOI興趣點(diǎn)算法
(3)數(shù)據(jù)傳輸協(xié)議protocol buffer
(4)Proto3協(xié)議定義
(5)構(gòu)建項(xiàng)目及用戶上線
(6)世界聊天
(7)上線位置信息同步
(8)移動(dòng)位置與AOI廣播
(9)玩家下線
(10)模擬客戶端AI模塊


1踏枣、寫在前面

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

? 設(shè)計(jì)Zinx的目的是我們可以通過(guò)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)

1-Zinx框架.png
zinx-start.gif

三娃弓、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) 

關(guān)于作者:

作者:Aceld(劉丹冰)

mail: danbing.at@gmail.com
github: https://github.com/aceld
原創(chuàng)書籍gitbook: http://legacy.gitbook.com/@aceld

創(chuàng)作不易, 共同學(xué)習(xí)進(jìn)步, 歡迎關(guān)注作者, 回復(fù)"zinx"有好禮

作者微信公眾號(hào)

文章推薦

開源軟件作品

(原創(chuàng)開源)Zinx-基于Golang輕量級(jí)服務(wù)器并發(fā)框架[完整版(附教程視頻)]
(原創(chuàng)開源)Lars-基于C++負(fù)載均衡遠(yuǎn)程調(diào)度系統(tǒng)[完整版]

精選文章

使用Golang的interface接口設(shè)計(jì)原則
深入淺出Golang的協(xié)程池設(shè)計(jì)
Go語(yǔ)言構(gòu)建微服務(wù)一站式解決方案
Golang中的局部變量“何時(shí)棧?何時(shí)堆?”


原創(chuàng)聲明:未經(jīng)作者允許請(qǐng)勿轉(zhuǎn)載,或者轉(zhuǎn)載請(qǐng)注明出處!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末他嫡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子庐完,更是在濱河造成了極大的恐慌钢属,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件门躯,死亡現(xiàn)場(chǎng)離奇詭異淆党,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)讶凉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門染乌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人懂讯,你說(shuō)我怎么就攤上這事荷憋。” “怎么了褐望?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵台谊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我譬挚,道長(zhǎng),這世上最難降的妖魔是什么酪呻? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任减宣,我火速辦了婚禮,結(jié)果婚禮上玩荠,老公的妹妹穿的比我還像新娘漆腌。我一直安慰自己缠沈,他們只是感情好佳晶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般淤齐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上憨愉,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天艰额,我揣著相機(jī)與錄音,去河邊找鬼劳景。 笑死誉简,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的盟广。 我是一名探鬼主播闷串,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼筋量!你這毒婦竟也來(lái)了烹吵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤桨武,失蹤者是張志新(化名)和其女友劉穎肋拔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玻募,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡只损,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了七咧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跃惫。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖艾栋,靈堂內(nèi)的尸體忽然破棺而出爆存,到底是詐尸還是另有隱情,我是刑警寧澤蝗砾,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布先较,位于F島的核電站,受9級(jí)特大地震影響悼粮,放射性物質(zhì)發(fā)生泄漏闲勺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一扣猫、第九天 我趴在偏房一處隱蔽的房頂上張望菜循。 院中可真熱鬧,春花似錦申尤、人聲如沸癌幕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)勺远。三九已至橙喘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胶逢,已是汗流浹背厅瞎。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宪塔,地道東北人磁奖。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像某筐,于是被迫代替她去往敵國(guó)和親比搭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353