{"id":14983607,"url":"https://github.com/slclub/easy","last_synced_at":"2025-04-10T19:04:30.937Z","repository":{"id":206933929,"uuid":"712329647","full_name":"slclub/easy","owner":"slclub","description":"A simple and fully functional network framework. Including TCP websocket grpc and service discovery and so on.","archived":false,"fork":false,"pushed_at":"2024-08-24T11:30:22.000Z","size":8833,"stargazers_count":6,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T16:46:01.012Z","etag":null,"topics":["easy","framework","game","go","grpc","net-framework","rpc-etcd"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/slclub.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-31T08:56:15.000Z","updated_at":"2024-08-24T11:30:26.000Z","dependencies_parsed_at":"2024-06-17T06:27:02.805Z","dependency_job_id":"719e2e87-a81b-46d3-b867-c7d91715309b","html_url":"https://github.com/slclub/easy","commit_stats":{"total_commits":47,"total_committers":1,"mean_commits":47.0,"dds":0.0,"last_synced_commit":"bf6902e198e722b0e1aec06a35bb991ae26b72fe"},"previous_names":["slclub/easy"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slclub%2Feasy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slclub%2Feasy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slclub%2Feasy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slclub%2Feasy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slclub","download_url":"https://codeload.github.com/slclub/easy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248279196,"owners_count":21077406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["easy","framework","game","go","grpc","net-framework","rpc-etcd"],"created_at":"2024-09-24T14:07:35.045Z","updated_at":"2025-04-10T19:04:30.916Z","avatar_url":"https://github.com/slclub.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EASY  FRAMEWORK\n[![license](https://img.shields.io/badge/License-MIT_2023-blue)](https://github.com/slclub/easy/blob/master/LICENSE)\n\n## Summary\n\nA light net framework writen with golang.  You can use it to write games,web,or chat and so on.\n\nEasy framework biggest advantage is light, flexibility and customeize. you can change some component of Easy to adapt to your needs.\n\nIt includes various Network Transport Protocol such as TCP,websocket,HTTP. The TCP transmission rule can be customed too.\nso,in addition to using default rules, you can also choose your own rules, but you need to implement the interface of Rule.\n\n## Directory\n- [Installation](#Installation)\n- [Quick Start](#quick-start)\n- [Router for keepalive](#Router-for-keepalive)\n- [ListenServers](#ListenServers)\n- [Customize](#Customize)\n- [Open Packages](#Open-packages)\n- [NETS](#NETS)\n- [RPC and discovery](#RPC)\n- [Examples](#Examples)\n- [Building With Docker](#Building-With-Docker)\n- [Contribution](#Contribution)\n- [License](#License)\n\n## Installation\n```go\ngo get github.com/slclub/easy\n```\n\nIf you want the more detaild tutorial. Please refer to the sample testing project in the examples directory .\n\n## Quick Start\n\n\u003e### Start Listen Servers\n\n- import\n```go\n\nimport (\n    \"github.com/slclub/easy/nets/agent\"\n    \"github.com/slclub/easy/servers\"\n    \"github.com/slclub/easy/typehandle\"\n)\n```\n\n- Set\n\nRegiste server with your configruation.Here we use the websocket server(servers.WSServer) as an example.\n\n```go\nserver1 = servers.NewWSServer()\n\nserver1.Init(\u0026agent.Gate{\n    Addr:            \":18080\",\n    Protocol:        typehandle.ENCRIPT_DATA_JSON,\n    PendingWriteNum: 2000,\n    LittleEndian:    true,\n    MaxConnNum:      2000,\n})\n```\n\n- Start\n\nPlease use the easy.Serv to start all of your listening servers. \nyou can start more than one listening server.Each server has its owned network protocol.\n\n```go\n\nfunc Start() {\n    easy.Serv(\n        lservers.Server1(), // websocket 监听服务 可以有多个\n        //lservers.Server2(), // tcp 服务\n    )\n}\n\n```\n\n\u003e### registe\nRegiste message id and message struct and handle to the router of servers\n\nEach server has a corresponding router.\n\n```go\n// \"github.com/slclub/easy/typehandle\"\nr1 := lservers.Server1().Router()\nr1.Register(ID.LOGIN_RES, \u0026json.LoginRes{}, nil)\nr1.Register(ID.LOGIN_REQ, \u0026json.LoginReq{}, typehandle.HandleMessage(login.HandleLogin))\n```\n\n\u003e### handle \n\nHandle is a listening service  and processing function.\nIn the other word it's a controller(The C of MVC).\n\nIt is an entry function of logical business.\n\n- First Argument\n\nIt is a Agent object. You just need to understand  like a link.\n\n- Second Argument\n\nIt is a message that you defined. \n\nPlease used the Pointer type of Golang.\n\n- example\n\n```go\nimport (\n    \"github.com/slclub/easy/nets/agent\"\n    \"reflect\"\n    \"simple/vendors/log8q\"\n)\n\nfunc HandleLogin(agent1 agent.Agent, arg any) {\n    log8q.Log().Info(\"WS controller.Handle.Login info: \", reflect.TypeOf(arg).Elem().Name())\n    // agent1.WriteMsg(nil)\n}\n\nfunc HandleLoginTcp(agent2 agent.Agent, arg any) {\n    log8q.Log().Info(\"TCP controller.Handle.Login info: \", reflect.TypeOf(arg).Elem().Name())\n}\n```\n\n\n## Router for keepalive\nRouter is the link between servers and handle. All parts of the router are implemented using interfaces.\nso,you can custome it by your self. especially for Binder and Encoder that they are related to rules and data tranmited .\n\n\u003e### Router\n\n- definition\n\n```go\ntype Router interface {\n    element.Distributer\n    Register(ID element.MID, msg any, handle typehandle.HandleMessage)\n    Route(msg any, ag any) error\n    PathMap() *element.PathMap\n}\n```\n\n```go\n\n// 为route 绑定插件\ntype Distributer interface {\n    DistributePlug\n    // 绑定 解码器=typehandle.Encoder ; 绑定器 = element.Binder\n    // Binding(encoder typehandle.Encoder, binder Binder)\n    Binding(plugins ...any)\n}\n\ntype DistributePlug interface {\n    Binder() Binder\n    Encoder() encode.Encoder\n}\n```\n\n- Binding method\n\nThe ```Binding(plugins ...any)``` method  can bind binder and encoder to Router. \nSo use this method to replace Binder and Encoder if you want to custom yourself.\n\nexample:\n\n```go\nr := Server1().Router()\nr.Binding(bind.NewBindJson(r.PathMap()), encode.NewJson(r.PathMap()))\n```\n\n- PathMap\n\nThis method return the storage for routing. Binder and Encoder should use it together. \n\n\n\u003e ### Encoder\n\nEncode/Decode transferred data. you can also customize this component.\nBy default, we support two types : json and protobuf.\n\n- Interface\n\n```go\n// stream 解析器 encode decode操作\ntype Encoder interface {\n\tUnmarshal(data []byte) (any, error)\n\tMarshal(msg any) ([]byte, error)\n\tLittleEndian(...bool) bool\n}\n```\n\n- JSON\n\n- Protobuf\n\n\u003e### Binder\n\nIt has three basic functions: binding Encoder, binding handle and route functions.\nIt corresponds one-to-one with the encoder. the methods of Register, RegisterHandle and Route will be called by Router\n\n- Interface\n\n```go\ntype Binder interface {\n    // 绑定消息ID 和消息\n    Register(id MID, msg any)\n    // 绑定 handle 到 路由\n    RegisterHandle(id MID, handle typehandle.HandleMessage)\n    // 继承执行器\n    RouteExecuter\n}\n\n\ntype RouteExecuter interface {\n    // 路由分发消息  给 对应的handle\n    Route(msg any, ag any) error\n}\n```\n\n\n\n## ListenServers\nI had defined various servers followed by network protocol.\n\nAny of them can be New. so It is very convenient to use more than one servers in your project.\nAny instance servers can use different components. Also they can be customed.\n\nThe Listen Server like a container of components, \nenable smooth collaboration among various components to complete tasks.\n\n\u003e### interface\nAll of the servers should implement the interface of ```ListenServer```.\nThey will all be used uniformly in the easy.Serv().\n\n```go\n\nimport (\n    \"github.com/slclub/easy/nets/agent\"\n    \"github.com/slclub/easy/route\"\n)\n\ntype ListenServer interface {\n    Init(*agent.Gate)\n    OnInit()\n    Router() route.Router\n    Start()\n    Hook() *hookAgent // agent 链接 回调\n    //OnClose(func())\n    Close()\n}\n```\n\n\u003e### websocket\n\n- Name\n\n```\nWSServer\n```\n\n- Create\n\n```go\n// import github.com/slclub/easy/servers\nservers.NewWSServer()\n```\n\n\n\u003e### TCP\n\n- Name\n\n```\nTCPServer\n```\n\n- Create\n\n```go\n// import github.com/slclub/easy/servers\nservers.NewTCPServer()\n```\n\n\u003e### WEB\n\n## Customize \n\n### components:\n\n- Listen Server\n- Router\n- route.Binder\n- route.Encoder\n- Agent Of Net\n- FromConnReadWriter of conns\n- Conn of conns\n\n\n## Open Packages\n\n[option package](https://github.com/slclub/easy/blob/master/docs/option.md)\n\n[aoi package](https://github.com/slclub/easy/blob/master/docs/aoi.md)\n\n[events package](https://github.com/slclub/easy/blob/master/docs/events.md)\n\n[log8q package](https://github.com/slclub/log8q)\n\n\n---- \n\n## NETS\n\n\u003e### agent.Agent\n\nWhen you send or recvive messages from client,you will need to use this.\n\nThe first argment of the handle that registed in your Router is agent.Agent type.\n\nYou will bind it to your own entity.\n\n```go\ntype Agent interface {\n    WriteMsg(msg any)\n    LocalAddr() net.Addr\n    RemoteAddr() net.Addr\n    Close()\n    Destroy()\n    UserData() any\n    SetUserData(data any)\n    LoopRecv(handle AgentHandle)\n}\n```\n\n- Send Message\n\n```Agent.WriteMsg(msg any)```\n\n- Recive Message\n\nWill be called by Router Excuter. So we do not need to care about it.\n\nThe handle functions is the processor that receives messages.\n\n\n\u003e### conns.Conn\n\nIt is does not matter with the logical business. Just open for framework customed.\n\n```go\ntype Conn interface {\n    ReadMsg() ([]byte, error)\n    WriteMsg(args []byte) error\n    LocalAddr() net.Addr\n    RemoteAddr() net.Addr\n    Close()\n    Destroy()\n    Done() chan struct{}\n    GetOption() *Option\n}\n```\n\n## RPC\n\nThe easy framework program integrates GRPC and ETCD. constitutes a complete service discovery and distributed RPC communication server architecture.\n\neasy\n\n[tutorials and example](https://github.com/slclub/easy/tree/master/examples#RPC)\n\n[ETCD with docker](https://github.com/slclub/easy/blob/master/docs/etcd.md)\n\n[grpc-go 官网](https://grpc.io/docs/languages/go/)\n\n[etcd 官网](https://etcd.io/docs/)\n\ndocker image (```quay.io/coreos/etcd```). Ofcourse, you can used any image according to your preferences.  \n\n## Examples\n\n[Detail](https://github.com/slclub/easy/tree/master/examples/)\n\n## Building With Docker\nUnder Construction.\n## Contribution\n## License\n\nCopyright (c) 2023 许亚军\n\n[MIT](https://github.com/slclub/easy/blob/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslclub%2Feasy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslclub%2Feasy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslclub%2Feasy/lists"}