{"id":13413599,"url":"https://github.com/fish-tennis/gnet","last_synced_at":"2026-04-02T12:51:19.912Z","repository":{"id":54472723,"uuid":"424510132","full_name":"fish-tennis/gnet","owner":"fish-tennis","description":"high performance net library for game server","archived":false,"fork":false,"pushed_at":"2024-06-07T10:05:56.000Z","size":245,"stargazers_count":15,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-07-31T20:52:35.856Z","etag":null,"topics":["game","go","golang","net","protobuf","server","tcp","websocket"],"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/fish-tennis.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":"2021-11-04T07:40:48.000Z","updated_at":"2024-06-19T13:53:44.000Z","dependencies_parsed_at":"2024-03-14T12:25:30.565Z","dependency_job_id":"a5f10f20-d4dd-4609-9544-3633742ba724","html_url":"https://github.com/fish-tennis/gnet","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fish-tennis%2Fgnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fish-tennis%2Fgnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fish-tennis%2Fgnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fish-tennis%2Fgnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fish-tennis","download_url":"https://codeload.github.com/fish-tennis/gnet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243635606,"owners_count":20322967,"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":["game","go","golang","net","protobuf","server","tcp","websocket"],"created_at":"2024-07-30T20:01:44.157Z","updated_at":"2026-04-02T12:51:19.904Z","avatar_url":"https://github.com/fish-tennis.png","language":"Go","funding_links":[],"categories":["Networking","网络"],"sub_categories":["Transliteration","音译"],"readme":"# gnet\n[![Go Report Card](https://goreportcard.com/badge/github.com/fish-tennis/gnet)](https://goreportcard.com/report/github.com/fish-tennis/gnet)\n[![Go Reference](https://pkg.go.dev/badge/github.com/fish-tennis/gnet.svg)](https://pkg.go.dev/github.com/fish-tennis/gnet)\n[![codecov](https://codecov.io/gh/fish-tennis/gnet/branch/main/graph/badge.svg?token=RJ1C0OJAMK)](https://codecov.io/gh/fish-tennis/gnet)\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go#networking)\n\n[中文说明](https://github.com/fish-tennis/gnet/blob/main/README_cn.md)\n\nHigh performance network library,especially for game servers\n\n## Features\n- MultiThread, nonblocking\n- Default support protobuf\n- Optimize receiving and dispatching using lockless RingBuffer, which can improve performance by 5x for some cases\n- Easy to implement custom encoding and decoding\n- rpc\n- Support Tcp,WebSocket(ws and wss)\n\n## Usage\nrun a server\n```go\ncodec := gnet.NewProtoCodec(nil)\nhandler := gnet.NewDefaultConnectionHandler(codec)\nhandler.Register(gnet.PacketCommand(pb.CmdTest_Cmd_TestMessage), onTestMessage, new(pb.TestMessage))\nlistenerConfig := \u0026gnet.ListenerConfig{\n    AcceptConfig: gnet.DefaultConnectionConfig,\n}\nlistenerConfig.AcceptConfig.Codec = codec\nlistenerConfig.AcceptConfig.Handler = handler\ngnet.GetNetMgr().NewListener(ctx, \"localhost:10001\", listenerConfig)\n```\n\nrun a client\n```go\ncodec := gnet.NewProtoCodec(nil)\nhandler := gnet.NewDefaultConnectionHandler(codec)\nhandler.Register(gnet.PacketCommand(pb.CmdTest_Cmd_TestMessage), onTestMessage, new(pb.TestMessage))\nconnectionConfig := gnet.DefaultConnectionConfig\nconnectionConfig.Codec = clientCodec\nconnectionConfig.Handler = clientHandler\nconnector := gnet.GetNetMgr().NewConnector(ctx, \"localhost:10001\", \u0026connectionConfig, nil)\nconnector.SendPacket(gnet.NewProtoPacket(gnet.PacketCommand(pb.CmdTest_Cmd_TestMessage),\n    \u0026pb.TestMessage{\n        Name: \"hello\",\n    }))\n```\n\n## Encoding and decoding(https://github.com/fish-tennis/gnet/blob/main/codec.go)\n\ngnet divide TCP stream based decoding into three layers\n\nLayer1:subcontracting stream, format:|Length|Data|,after receiving full packet content, hand it over to the next layer for processing\n\nLayer2:Decoding the data from Layer1,such as decryption,decompression,etc\n\nLayer3:protobuf deserialize,generate proto.Message\n\n![length \u0026 data](https://github.com/fish-tennis/doc/blob/master/imgs/gnet/packet.png)\n\n![encode](https://github.com/fish-tennis/doc/blob/master/imgs/gnet/packet_encode.png)\n\n![decode](https://github.com/fish-tennis/doc/blob/master/imgs/gnet/packet_decode.png)\n\n\n## Use RingBuffer to increase performance\n\n![ringbuffer-performance](https://github.com/fish-tennis/doc/blob/master/imgs/gnet/ringbuffer-performance.png)\n\n## rpc\nRpc send a request to target and block wait reply,similar to grpc-go,but gnet use command id instead of method name\n```go\nrequest := gnet.NewProtoPacket(cmd, \u0026pb.HelloRequest{\n    Name: \"hello\",\n})\nreply := new(pb.HelloReply)\nerr := connection.Rpc(request, reply)\nif err != nil {\n    return\n}\nlogger.Info(\"reply:%v\", reply)\n```\n\n## goroutine\n\n![connection_goroutine](https://github.com/fish-tennis/doc/blob/master/imgs/gnet/connection_goroutine.png)\n\n## Examples\nexample/helloworld: a simple example use protobuf message\n\nexample/data_packet: a simple example use DataPacket\n\nexample/custom_packet: how to extend custom packet struct\n\nexample/tcp_connection_simple: use protobuf message without RingBuffer\n\nexample/packet_size: send big packet which size is bigger than RingBuffer's cap\n\nexample/websocket: a simple example use websocket\n\nexample/rpc: how to use rpc\n\nexample/simulate_game: a performance test with a game application scenario\n\n## Client Connector Library\nC#: [gnet_csharp](https://github.com/fish-tennis/gnet_csharp)\n\n## Project\n\n\n[distributed game server framework](https://github.com/fish-tennis/gserver)\n\ngnet is also used in our commercial online game projects\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffish-tennis%2Fgnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffish-tennis%2Fgnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffish-tennis%2Fgnet/lists"}