Lightweight, facility, high performance golang based game server framework

Nano Build Status GoDoc Go Report Card MIT licensed

Nano is an easy to use, fast, lightweight game server networking library for Go. It provides a core network architecture and a series of tools and libraries that can help developers eliminate boring duplicate work for common underlying logic. The goal of nano is to improve development efficiency by eliminating the need to spend time on repetitious network related programming.

Nano was designed for server-side applications like real-time games, social games, mobile games, etc of all sizes.

How to build a system with Nano

What does a Nano application look like?

The simplest "nano" application as shown in the following figure, you can make powerful applications by combining different components.

Application

In fact, the nano application is a collection of  Component , and a component is a bundle of  Handler, once you register a component to nano, nano will register all methods that can be converted to Handler to nano service container. Service was accessed by Component.Handler, and the handler will be called while client request. The handler will receive two parameters while handling a message:

  • *session.Session: corresponding a client that apply this request or notify.
  • *protocol.FooBar: the payload of the request.

While you had processed your logic, you can response or push message to the client by session.Response(payload) and session.Push('eventName', payload), or returns error when some unexpected data received.

How to build distributed system with Nano

Nano contains built-in distributed system solution, and make you creating a distributed game server easily.

See: The distributed chat demo

The Nano will remain simple, but you can perform any operations in the component and get the desired goals. You can startup a group of Nano application as agent to dispatch message to backend servers.

How to execute the asynchronous task

func (manager *PlayerManager) Login(s *session.Session, msg *ReqPlayerLogin) error {
    var onDBResult = func(player *Player) {
        manager.players = append(manager.players, player)
        s.Push("PlayerSystem.LoginSuccess", &ResPlayerLogin)
    }
    
    // run slow task in new gorontine
    go func() {
        player, err := db.QueryPlayer(msg.PlayerId) // ignore error in demo
        // handle result in main logical gorontine
        nano.Invoke(func(){ onDBResult(player) })
    }
    return nil
}

Documents

Resources

Community

Successful cases

Go version

> go1.8

Installation

go get github.com/lonng/nano

# dependencies
go get -u github.com/golang/protobuf
go get -u github.com/gorilla/websocket

Benchmark

# Case:   PingPong
# OS:     Windows 10
# Device: i5-6500 3.2GHz 4 Core/1000-Concurrent   => IOPS 11W(Average)
# Other:  ...

cd $GOPATH/src/github.com/lonng/nano/benchmark/io
go test -v -tags "benchmark"

License

MIT License

Owner
Lonng
Senior Infrastructure Engineer @pingcap
Lonng
Comments
  • Detect rpc call success

    Detect rpc call success

    Hi,

    if err := s.RPC("TopicService.NewUser", request); err != nil {
    		return errors.Trace(err)
    	}
    

    above code is in cluster example. How can i check TopicService.NewUser is success or error. Currenty error is traced only when the TopicService down

    thank you.

  • Handshake Package 中如何自定义握手数据验证

    Handshake Package 中如何自定义握手数据验证

    Handshake Package 中如何自定义握手数据验证

    client demo和文档中有出现 { "sys": { "version": "1.1.1", "type": "js-websocket" }, "user": { // Any customized request data } } 的描述 code - 握手响应的状态码。目前的取值:200代表成功,500为处理用户自定义握手流程时失败,501为客户端版 本号不符合要求。 sys.heartbeat - 可选,心跳时间间隔,单位为秒,没指定表示不需要心跳。 dict - 可选,route字段压缩的映射表,没指定表示没有字典压缩。 protos - 可选,protobuf压缩的数据定义,没有表示没有protobuf压缩。 user - 可选,用户自定义的握手数据,没有表示没有用户自定义的握手数据。

    服务端关于user的数据如何验证?

  • the tadpole demo run problem

    the tadpole demo run problem

    **/github.com/lonnng/nano/app.go:120: Upgrade failure, URI=/favicon.ico, Error=websocket: the client is not using the websocket protocol: 'upgrade' token not found in 'Connection' header

    how to solve the problem

  • cluster: maitain heartbeart between nodes in the same cluster

    cluster: maitain heartbeart between nodes in the same cluster

    What problem does this PR solve?

    1.Master与Members之间通过RPC调动建立心跳。让Master有主动踢掉异常节点的能力。 2.通过节点上报心跳信息,可以让Master重启或更新后,第一时间知道注册信息,其他节点无需通过重启再次注册。 3.最终保持 集群健康,和解耦 节点间的发布顺序与关联。方便多样式部署。 4.hook一个 OnUnregister fn,当节点异常做一些处理,比如报警。

    What is changed and how it works?

    1.通过在 Register proto + IsHeartbeat 字段,走不同的注册逻辑。记录心跳时间,每次 心跳注册 时检查一下所有节点的上报时间。 2.普通member定时向master调用心跳注册。

    关于测试: 启动 1 master 2Gate 3 chat,
    1chat可以开一个 mock exception exit 的方法。此时 master 会有主动 剔除异常 chat 的行为,具体可看日志。 2.当master重启,模拟master更新操作, 其他节点不用重启, master 的集群信息会自动恢复

  • cluster: decode optimization

    cluster: decode optimization

    What problem does this PR solve?

    1. decode优化,剩余包处理
    2. group测试bug修复
    3. 其他代码、注释优化

    What is changed and how it works?

    Check List

    Tests

    • Unit test
    • Integration test
    • Manual test (add detailed scripts or steps below)
    • No code

    Side effects

    • Possible performance regression
    • Increased code complexity
    • Breaking backward compatibility

    Related changes

    • Need to cherry-pick to the release branch
    • Need to update the documentation
    • Need to be included in the release note
  • 如何让comment在指定的goroutine中运行?

    如何让comment在指定的goroutine中运行?

    1.我想让不同的comment在不同的goroutine中运行,但是 只看到了handler中的localProcess的注释和schd的定义, 但是没有example,希望可以写个eample演示一下.万分感谢

    2.看了下关于分布式的实现,很想知道为什么不用成熟的etcd,consul方案,需要自己实现一下注册中心呢?

  • Chat example is not working because of nano.ListenWS( ) is not defined

    Chat example is not working because of nano.ListenWS( ) is not defined

    Bug Report

    Please answer these questions before submitting your issue. Thanks!

    1. What did you do? If possible, provide a recipe for reproducing the error.

    I Tried to run the chat example, using go run main.go but it wasn't possible because of the nano.ListenWS is no longer available.

    2. What did you expect to see?

    Chat example running

    3. What did you see instead?

    ./main.go:153:2: undefined: nano.ListenWS

    4. Versions of the nano

    I cloned the repository at 2019-08029, not sure the version.

  • close of closed channel when `Close` session in concurrent context

    close of closed channel when `Close` session in concurrent context

    package main
    
    import (
    	"errors"
    	"fmt"
    	"sync/atomic"
    	"time"
    )
    
    type test struct {
    	status int32
    	chDie  chan struct{}
    }
    
    func (t *test) Close() error {
    	if atomic.LoadInt32(&t.status) > 0 {
    		return errors.New("closed test")
    	}
    
    	// wait another gorontine enter block
    	time.Sleep(time.Second)
    
    	atomic.StoreInt32(&t.status, 1)
    
    	close(t.chDie)
    	return nil
    }
    
    func main() {
    	fmt.Println("Hello, 世界")
    	t := &test{chDie: make(chan struct{})}
    
    	go t.Close()
    	go t.Close()
    
    	time.Sleep(3 * time.Second)
    }
    

    Session.Close will occur the same problem show in above.

  • 多Gate sessionId 无法保证全局唯一

    多Gate sessionId 无法保证全局唯一

    Question

    当需要水平扩展 Gate时,无法保证 session id 全局唯一。 当前实现方式是依据 session id 标记 session 资源。 当出现 CloseSession 的时候,如果不同的用户出现相同的 sessionId, 是否会导致 close 误伤? 经测试 相同的sessionId 确实存在。 当初要采用 session id, 而不是采用 uid 方式关联,是基于什么思考? 有其他方式可以绕开这一问题吗?

  • 增加kcp支持和一个使用kcp的坦克demo

    增加kcp支持和一个使用kcp的坦克demo

    What problem does this PR solve?

    kcp 协议支持

    三方库为: github.com/xtaci/kcp-go

    What is changed and how it works?

    1. 增加 kcp 支持
    2. 增加 demo (使用kcp的坦克)

    本来kcp支持很简单,几行就能支持了, 之前也没考虑要pr,我在写这个过程中,写了个 tank demo,这样 pr 内容看起来有点乱。

    要是介意新增的 demo ,就不用合了, 麻烦作者抽空加一下 kcp 就好了。

  • fix session not closed

    fix session not closed

    What problem does this PR solve?

    What is changed and how it works?

    Check List

    Tests

    • Unit test
    • Integration test
    • Manual test (add detailed scripts or steps below)
    • No code

    Side effects

    • Possible performance regression
    • Increased code complexity
    • Breaking backward compatibility

    Related changes

    • Need to cherry-pick to the release branch
    • Need to update the documentation
    • Need to be included in the release note
  • expose remote service route for user custom

    expose remote service route for user custom

    What problem does this PR solve?

    in cluster mode, framework rpc remote service is randmom, user can't control the rule. so expose remote service route for user custom, it's useful for remote service shardding and support same service node expand horizontal.

    What is changed and how it works?

    exist multiple same remote service node, gate distribution rpc request can use user specify remoteAddr.

    Check List

    Tests has a example in examples/customerroute

    • Unit test
    • Integration test
    • Manual test (add detailed scripts or steps below)
    • No code

    Side effects

    • Possible performance regression
    • Increased code complexity
    • Breaking backward compatibility

    Related changes

    • Need to cherry-pick to the release branch
    • Need to update the documentation
    • Need to be included in the release note
  • 如何拓展使用MongoDB?

    如何拓展使用MongoDB?

    Question

    Before asking a question, make sure you have:

    • Searched existing Stack Overflow questions.
    • Googled your question.
    • Searched open and closed GitHub issues
  • What is the cluster restart sequence after a code change?

    What is the cluster restart sequence after a code change?

    Question

    What is the cluster restart sequence after a code change? Does it support independent restart? The problem currently encountered is that the session is not synchronized after restarting a service alone.

    ✅Searched existing Stack Overflow questions. ✅Googled your question. ✅Searched open and closed GitHub issues

  • nano should add uid in gRPC request

    nano should add uid in gRPC request

    Since nano did not implement SESSION-UID binding broadcast like pomelo, I think that nano should add uid with SessionID in gRPC request so that user could maintain unique sid-uid binding at frontend named "connector"

  • Kick数据包类型并没有实现封装调用入口吗

    Kick数据包类型并没有实现封装调用入口吗

    Question @lonng

    // Kick represents a kick off packet Kick = 0x05 // disconnect message from server

    请问这个数据包类型并没有实现吗? 源码没有一个地方调用过该类型。应该需要额外加一个类似s.Response接口来处理Kick类型的数据包吧。

    客户端虽然有这个数据包类型的定义接收,但是服务端没有实现这个数据包类型的封装? handlers[Package.TYPE_KICK] = onKick;

a framework in golang for game server or app server
a framework in golang for game server or app server

einx a framework in golang for game server or app server. a example server for einx (https://github.com/Cyinx/game_server_einx) Features User-Friendly

Dec 8, 2022
Fab.io is a lightweight game backend framework written in Go (Golang).

Fab.io is a lightweight real-time game backend framework written in Go (Golang).

Jun 20, 2022
A lightweight and efficient messaging gateway server for distributed game servers, written in Go.

Overview channeld is an open source, light-weight and efficient messaging gateway server designed for distributed game servers (typically MMO) and oth

Aug 8, 2022
A game server framework in Go (golang)

Leaf A pragmatic game server framework in Go (golang). Features Extremely easy to use Reliable Multicore support Modularity Community QQ 群:376389675 D

Jan 2, 2023
Scalable game server framework with clustering support and client libraries for iOS, Android, Unity and others through the C SDK.

pitaya Pitaya is an simple, fast and lightweight game server framework with clustering support and client libraries for iOS, Android, Unity and others

Jan 2, 2023
A game server side framework with both web API and realtime communication.

HAYABUSA Framework Hayabusa is a server side framework for Japan-like social games. Easy to understand and use for beginners Powerful controller, flex

May 21, 2022
Arkanoid game in Go using Ebiten game engine with ECS.
Arkanoid game in Go using Ebiten game engine with ECS.

Arkanoid-go Arkanoid game in Go using Ebiten game engine with ECS. You must have Git LFS installed when cloning the repository to download assets. See

Oct 9, 2022
AircraftWar - a game powered by Go+ spx game engine
AircraftWar - a game powered by Go+ spx game engine

AircraftWar - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download thi

Jan 5, 2022
FlappyCalf - a game powered by Go+ spx game engine
FlappyCalf - a game powered by Go+ spx game engine

FlappyCalf - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download this

Nov 6, 2022
FlappyCalf - a game powered by Go+ spx game engine
FlappyCalf - a game powered by Go+ spx game engine

FlappyCalf - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download this

Nov 6, 2022
MazePlay - a game powered by Go+ spx game engine
MazePlay - a game powered by Go+ spx game engine

MazePlay - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download this g

Dec 16, 2021
A simple game that I created with Ebiten game library as a way to teach myself Go. Enjoy!
A simple game that I created with Ebiten game library as a way to teach myself Go. Enjoy!

galactic-asteroid-belt Overview A simple game that I created with Ebiten game library as a way to teach myself Go. Enjoy! Run To run, you will need Go

Dec 2, 2021
RundQuiz-Game - This is a Go exercise that implements and builds a quiz game from a list of math questions in a CSV file.

Go RundQuiz Game Exercise details This exercise is broken into two parts to help simplify the process of explaining it as well as to make it easier to

Jan 5, 2022
Simple 2D game to teach myself various things about game development and ECS, etc

2d-grass-game I really don't know what to name this game. Its a big grass field, and its in 2d so....2D Grass game This is a simple 2D game to teach m

Jan 17, 2022
A Game Server Skeleton in golang.
A Game Server Skeleton in golang.

A game server skeleton implemented with golang. 注意(NOTICE) 欢迎加入QQ群: 459420581 (Gopher成都,讨论一切与go有关的话题) gonet/2 gonet1已停止维护(I no longer maintain this, p

Dec 26, 2022
Scalable Distributed Game Server Engine with Hot Swapping in Golang
Scalable Distributed Game Server Engine with Hot Swapping in Golang

GoWorld Scalable Distributed Game Server Engine with Hot Reload in Golang Features Architecture Introduction Get GoWorld Manage GoWorld Servers Demos

Dec 25, 2022
game server by golang

使用golang开发的框架 How to use ? 参考 main.go Features kernel使用channel 和 goroutine 模拟的Actor模式 使用channel 模拟的消息队列 kernel.Context内部实现了一个链表,用于发起call的时候,由于自身channe

Dec 27, 2022
Simple 2D game prototyping framework.
Simple 2D game prototyping framework.

prototype Simply prototype 2D games using an easy, minimal interface that lets you draw simple primitives and images on the screen, easily handle mous

Dec 17, 2022
Dedicated Game Server Hosting and Scaling for Multiplayer Games on Kubernetes
Dedicated Game Server Hosting and Scaling for Multiplayer Games on Kubernetes

Agones is a library for hosting, running and scaling dedicated game servers on Kubernetes. Agones, is derived from the Greek word agōn which roughly t

Jan 6, 2023