1 Star 0 Fork 50

KingKong / RockGO

forked from 野猪大大 / RockGO 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

RockGO(go master分支泛型基本可以使用,本库使用泛型重构后发布)

重构 RockGO ECS engine: https://github.com/zllangct/ecs

  基于ECS(Entity component System)构建的分布式游戏服务端框架,同时提供Actor模型,目标是致力于快速搭建轻量、高性能、高可用的 分布式游戏后端,以及其他分布式后端应用。

  组件化的构架使得开发者不需要任何改动就能轻松实现一站式开发,分布式部署,规避分布式调试的困难,提升开发效率。框架提供udp、 tcp、websocket常用网络协议,同时提供优雅的协议接口,可让开发者轻松实现其他如kcp等网络协议的定制。

Installation:

$ go get -u github.com/zllangct/RockGO

Quick start:

当然用最简单的hello world告诉你一切都是如此的简单, 完整代码参见example: SingleNode ,更多的用法,参见example目录。

Config:

    {
        "MasterAddress": "127.0.0.1:6666",        //中心服务节点地址
        "LocalAddress": "127.0.0.1:6666",         //本节点服务地址
        "AppName": "defaultApp",                  //本节点服务的App名称
        "Role": [                                 //本节点的服务角色,角色可理解为按服务内容分服
            "master"                              //此处,默认为中心服务节点
        ],
        "NodeDefine": {                           //节点定义
            "node_gate": {                        //程序启动参数中,附加节点名参数可覆盖上面的默认
                "LocalAddress": "0.0.0.0:6601",   //默认参数,eg:go run main.go -node node_gate
                "Role": [                         //此时启动的便是node_gate对应的服务内容
                    "gate"                        //节点服务内容可自由搭配,单服或者分布式的选择只
                ]                                 //需要修改配置文件,不需要修改任何一行代码,做到
            },                                    //单站式开发,随心部署
            "node_login": {                        
                "LocalAddress": "0.0.0.0:6602",
                "Role": [                         //分布式部署:
                    "login"                       //物理机一:go run main.go -node node_master
                ]                                 //物理机二:go run main.go -node node_gate
            },                                    //物理机三:go run main.go -node node_room
            "node_login_gate": {
                "LocalAddress": "0.0.0.0:6603",   //go run main.go -node node_gate_gate 这样启动的
                "Role": [                         //便是一个节点同时具备 login 和 gate 两个角色的节点
                    "login",
                    "gate" 
                ]
            }
            "node_single": {
                "LocalAddress": "0.0.0.0:6604",   //go run main.go -node single 这样启动的
                "Role": [                         //便是所有服务在同一节点,即单服模式,小负载
                    "login",                      //或者开发阶段使用,方便调试
                    "gate" 
                    "master",
                    "room",
                    "location"
                ]
            }
        },        
        "NetConnTimeout": 9000,                 //外网连接心跳超时间隔,单位毫秒
        "NetListenAddress": "0.0.0.0:5555",     //外网服务端口
    }

Server:

    package main
    
    import (
    	"flag"
    	"fmt"
    	"github.com/zllangct/RockGO"
    	"github.com/zllangct/RockGO/component"
    	"github.com/zllangct/RockGO/gate"
    	"github.com/zllangct/RockGO/logger"
    )

    var Server *RockGO.Server
    
    func main()  {  
        //初始化服务节点
    	Server = RockGO.DefaultServer()  
    	
    	/*
    	    添加组件组
    	    添加网关组件(DefaultGateComponent)后,此服务节点拥有网关的服务能力。
    	    同理,添加其他组件,如登录组件(LoginComponent)后,拥有登录的服务内容。
    	*/
    	Server.AddComponentGroup("gate",[]Component.IComponent{&gate.DefaultGateComponent{}})
	
    	//开始服务
    	Server.Serve()
    }  

Client:

//默认网关采用websocket协议,可以使用任意websocket客户点连接测试。example中提供一个laya客户端供测试使用。

Feature:

1. ECS(Entity Component System)构架

  ECS全称Entity-Component-System(实体-组件-系统),是基于组合优于继承,即将不变的部分使用继承以方便复用, 将多变的部分用组合来方便拓展,是按照这种原则的一种设计模式。当然这种设计模式带来了许多比OOP更容易容实现 的特性,当然ECS并不是抛弃OOP,这是一个度的问题。ECS的特点和优势,暴雪在分享《守望先锋》的ECS服务构架的文 章中已经阐述比较详细(中文译文戳这里),也可以看看云风博客中的 讨论 (继续戳),此处都不赘述了。在服务端程序中 的优势,这里简要概括几点:

1.1 自由组合
    Component尽量按照原子性原则设计,只要有合适的功能拆分粒度,服务端可以随性所欲的组合,这在分布式构架
中至关重要,关系到服务端节点间功能的拆分组合。比如中心服务节点担任了游戏大厅和注册登录两项服务,随着用户
规模的扩大,中心节点需要把注册登录拆分出来单独成为节点。在ECS构架中,这将是非常容易的一件事,很少或者
甚至不需要任何修改一行功能代码就能实现,因为节点本身就是功能组件的组合,分服不过是根据配置文件重新组合一
次。这也微服务的思想走在了一起,微服务往往在服务间的调用走的是网络调用,但ECS构架下可以轻松的实现网络本地
调用的自主切换。单服就是真正的单服,本地调用,减少不必要的网络消耗,而不是多个服务部署在了同一台物理机上。
1.2 热插拔
    ECS构架下,实体和组件都能运行时添加删除,框架提供了Initialize、Awake、Start、Update、Destroy 内置系统,
这些内置系统能保证每一个功能组件,或者组件组合所需的完整生命周期。
1.3 易拓展
    功能的拓展,大多情况是新组件,新系统的设计,耦合性极低。
1.4 更优雅的停机
    所以对象都有完整的生命周期,Destroy系统可以保证每个对象在销毁时,得到正确的处理,实现更优雅的停机处理。
1.5 序列化
    所有组件,实现持久化接口之后,都具备序列化的能力。配合优雅的停机,很容易实现停机后的恢复。
1.7 高性能
    每个系统都不会遍历所有的对象,只会过滤出感兴趣的组件,专人专事,效率集中,减少调用,例如不需要Update处理的组件,便
不用实现Update接口,Update系统将不会遍历此组件。 
1.8 方便调试
    分布式调试的麻烦,这里并不存在,单机开发,随心大胆的断点,最后仅仅是一个配置参数完成分布式部署。
1.9 想到了再添加 ... ...

2. Actor 模式

  有空再详细写,反正知道对方的ActorID,无论他在哪儿,无论活在那个节点,Tell() 都能告诉他。框架内自主实现本地调用和RPC 调用的分流。Actor模式的特性与优势,看官自行G或者B。千万别问为什么有了ECS还能有Actor,并不冲突,ECS也是基于OOP实现的,所以Actor基于 ECS实现,而且比OOP实现Actor更简单。

3. RPC

  RPC的性能与可靠性是分布式系统中最重要的一环,游戏要的是效率,服务治理方面够用就行,所以并未选择市面上流行的服务治理型 的RPC调用框架,并且游戏构架本身就具备了服务治理的能力,但RPC框架自带的治理能力又不足以支撑游戏需求,所以略显多余,大体量的框架 复杂的环境配置大大的增加了维护、定制、学习、部署、迁移的难度,尤其对中小型开发者不友好。既要满足中小型项目需要的简易性, 又具有大型项目的扩展性,框架选用了go自带的rpc框架,其性能有目共睹,测评参照这里(戳我就行), 基于net/rpc作了轻量化定制,添加了必要的功能特性:

   (1). 超时机制  (2). 心跳检测 (3). 断线重连 (4). 单向调用 (5). 客户端回调

4. 网络协议

4.1 框架支持的网络协议

框架支持的网络协议有:TCP、UDP、Websocket、http,封包格式如下:

协议名称 协议格式 长度 数据类型
TCP Length-[Type-Data] 4 - [ 4 - n ] 二进制
UDP Length-[Session-Type-Data] 4 - [ 4 - 4 - n ] 二进制
Websocket Type-Data 4 - n 二进制

  http建议直接在网关组件中使用gin、fasthttp等http处理框架对应路由处理函数,http使用途中极有可能与页面有关,虽然 集成到上述方式路由中十分简单,但不建议这样处理,这样僵化了http的灵活性和丰富的功能特性。

4.2 自定义网络协议

  框架内可以很轻松的实现自定义协议的扩展,对原有协议都是非侵入的依赖,只需要简单封装,比如各种可靠UDP协议,KCP、UDT、 ENET等,只需要实现以下述接口:

    //网络协议
    type ServerHandler interface {
        Listen() error                      //监听
        Handle() error                      //处理
    }
    //链接对象
    type Conn interface {
    	WriteMessage(messageType uint32, data []byte) error   //消息发送
    	Addr() string                                         //目标地址
    	Close() error                                         //关闭
    }
    //解包协议
    type Protocol interface {
        ParsePackage( []byte) (int, int)                            //包处理
    	ParseMessage( context.Context,  []byte)([]uint32,[]byte)    //消息处理
    }
   

  网络协议的实现可参照TCP、UDP和Websocket。各种网络协议所提供链接对象可不相同, 需要实现连接对象接口进行统一,供Session使用。网络协议和链接对象接口的实现相对简单,不容 易产生歧义,其中解包协议参照TCP和Websocket用法:

/* TCP LTD protocol 
	Length—(Type—Data) ,数据长度—(消息类型—消息体) 大小:  4 — (4 — n)
*/
type LtdProtocol struct{}

//完整包中解析出消息ID和数据部分
func (s *LtdProtocol) ParseMessage(ctx context.Context,data []byte)([]uint32,[]byte){
    mt := binary.BigEndian.Uint32(data[:4])
    return []uint32{mt}, data[4:]
}

//检查包是否接受完整
func (s *LtdProtocol) ParsePackage(buff []byte) (pkgLen, status int) {
    if len(buff) < 4 {
        return 0, PACKAGE_LESS
    }
    length := binary.BigEndian.Uint32(buff[:4])
    
    if length > 1048576000 || len(buff) > 1048576000 { // 1000MB
        return 0, PACKAGE_ERROR
    }
    if len(buff) < int(length) {
        return 0, PACKAGE_LESS
    }
    return int(length), PACKAGE_FULL
}


/* Websocket TD protocol
	Type—Data ,消息类型—消息体 大小:  4 — n
*/
type TdProtocol struct{}

//解析消息ID和消息数据
func (s *TdProtocol) ParseMessage(ctx context.Context,data []byte)([]uint32,[]byte){
    mt := binary.BigEndian.Uint32(data[:4])
    return []uint32{mt}, data[4:]
}

//websocket 自带粘包处理,此处无需手动处理
func (s *TdProtocol) ParsePackage(buff []byte) (pkgLen, status int) {
    return 0,0
}

5. 消息序列化协议

5.1 支持的序列化协议
   (1). Json  (2). ProtoBuf
5.2 自定义序列化协议

  自定义序列化协议需要实现以下接口:

//消息解析协议
type MessageProtocol interface {
    Marshal( interface{})([]byte,error)         //序列化
    Unmarshal( []byte, interface{})error        //反序列化
}

7. 业务接口

7.1 路由规则

  框架提供消息的路由,无需用户手动对应消息的处理方法,框架根据函数自动判断是否为消息处理函数。需要满足以下条件 :

  (1). 结构体继承 ApiBase
  (2). 函数必须为结构体导出函数
  (3). 函数必须为以下结构:func (this *XXX) FunctionName(sess *network.Session,message *MessageStruct)
   第一参数为 会话Session,第二参数为消息对应的结构体,框架会更加第二参数去判断处理对应的消息。

  参见:

//协议对应字典,推荐使用工具生成该文件,以便前后端对应准确
//稍后会提供相应工具,目前完成了protobuf 导出c# 和 golang 的协议对应
//完善之后会更新至本仓库,由于过于简单,客官可自行完成
// 原理:1)读取proto文件 2)提取消息名 3)按照同一序号生成c#、golang或者其他语言文件(字符串拼接)

var Testid2mt = map[reflect.Type]uint32{
    reflect.TypeOf(&TestMessage{}):1,
    reflect.TypeOf(&TestLogin{}):2,
    reflect.TypeOf(&PlayerInfo{}):3,
}

//消息定义
type TestMessage struct {
    Name string
}
type TestReply struct {
    Result bool
}

//接口组定义
type TestApi struct {
    network.ApiBase         //继承ApiBase
}

/*
    使用协议接口时,需先初始化,初始化时需传入定义的消息号对应字典
    以及所需的消息序列化组件,可轻易切换为protobuf,msgpack等其他序列化工具
*/
func NewTestApi() *TestApi  {
    r:=&TestApi{}
    r.Instance(r).SetMT2ID(Testid2mt).SetProtocol(&MessageProtocol.JsonProtocol{})
    return r
}

//协议接口1  Hello,框架会自动判断TestMessage类型消息,自动路由至此函数处理
func (this *TestApi)Hello(sess *network.Session,message *TestMessage) {
    //打印消息
    println(fmt.Sprintf("Hello,%s", message.Name))

    //回复消息
    res:=&TestReply{
        Result:true,
    }
    this.Reply(sess,res)
}

//协议接口2  other,同理,该函数处理 Other 类型消息
func (this *TestApi) Other(sess *network.Session,message *Other) {
	......
}
7.1 自定义路由

  当然用户可以不用使用框架自带的消息路由方法,可以实现NetAPI接口自定义消息路由规则:

type NetAPI interface {
        Init()                                                                        //初始化
	Route(*Session, uint32, []byte)	                                              //反序列化并路由到api处理函数
	Reply(session *Session,message interface{})error                              //序列化消息并发送至客户端
}

8. Example列表

  组件定义范例
  Laya测试客户端
  Golang Websocket测试客户端
  分布式部署配置范例
  ECS单节点范例
  ECS+Actor单节点范例
  TCPUDP服务端客户端范例
  Websocket服务端范例

8. 计划任务

  (1). 完善现有example
  (2). 提供房间类游戏大厅、房间模型(就是你想的棋牌)
  (3). 增加Laya 客户端范例
  (4). 增加Unity 帧同步客户端范例
  (5). 增加KCP协议支持
  (6). 后台管理页面、数据统计页面
  (7). 节点平滑升级
  (8). 提供protobuf 前后端协议自动化对应工具
  。。。。。。

9. 写在后面

   致谢: gin — gin-gonicwebsocket—gorillago-component—shadowmintTarsGo—TarsCloud
   喜欢的朋友给个星星~

  【RockGO交流群①】(已满,请加②群)

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

简介

基于ECS(Entity component System)构建的分布式游戏服务端框架,同时提供Actor模型,目标是致力于快速搭建轻量、高性能、高可用的 分布式游戏后端,以及其他分布式后端应用 展开 收起
Go
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Go
1
https://gitee.com/gongsir/rockgo.git
git@gitee.com:gongsir/rockgo.git
gongsir
rockgo
RockGO
master

搜索帮助