Categorygithub.com/xixigame/nano
modulepackage
0.4.0
Repository: https://github.com/xixigame/nano.git
Documentation: pkg.go.dev

# README

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 has no built-in distributed system components, but you can easily implement it with gRPC and smux . Here we take grpc as an example.

  • First of all, you need to define a remote component
type RemoteComponent struct {
	rpcClients []*grpc.ClientConn
}
  • Second, fetch all grpc servers infomation from services like etcd or consul in nano lifetime hooks
type ServerInfo struct {
	Host string `json:"host"`
	Port int    `json:"port"`
}

// lifetime callback
func (r *RemoteComponent) Init() {
	// fetch server list from etcd
	resp, err := http.Get("http://your_etcd_server/backend/server_list/area/10023")
	if err != nil {
		panic(err)
	}
	
	servers := []ServerInfo{}
	if err := json.NewDecoder(resp.Body).Decode(&servers); err != nil {
		panic(err)
	}
	
	for i := range servers {
		server := servers[i]
		client, err := grpc.Dial(fmt.Sprintf("%s:%d", server.Host, server.Post), options)
		if err != nil {
			panic(err)
		}
		r.rpcClients = append(r.rpcClients, client)
	}
}

func (r *RemoteComponent) client(s *session.Session) *grpc.ClientConn {
	// load balance
	return r.rpcClients[s.UID() % len(s.rpcClients)]
}

// Your handler, accessed by:
// nanoClient.Request("RemoteComponent.DemoHandler", &pb.DemoMsg{/*...*/})
func (r *RemoteComponent) DemoHandler(s *session.Session, msg *pb.DemoMsg) error {
	client := r.client(s)
	// do something with client
	// ....
	// ...
	return nil
}

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/lonnng/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/lonnng/nano/benchmark/io
go test -v -tags "benchmark"

License

MIT License

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Functions

EnableDebug let 'nano' to run under debug mode.
Invoke invokes function in main logic goroutine.
Listen listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections.
ListenWS listens on the TCP network address addr and then upgrades the HTTP server connection to the WebSocket protocol to handle requests on incoming connections.
NewAfterTimer returns a new Timer containing a function that will be called after duration that specified by the duration argument.
NewCondTimer returns a new Timer containing a function that will be called when condition satisfied that specified by the condition argument.
NewCountTimer returns a new Timer containing a function that will be called with a period specified by the duration argument.
NewGroup returns a new group instance.
No description provided by the author
NewTimer returns a new Timer containing a function that will be called with a period specified by the duration argument.
Register register a component with options.
SetCheckOriginFunc set the function that check `Origin` in http headers.
SetDictionary set routes map, TODO(warning): set dictionary in runtime would be a dangerous operation!!!!!!.
SetHeartbeatInterval set heartbeat time interval.
SetLogger rewrites the default logger.
SetSerializer customize application serializer, which automatically Marshal and UnMarshal handler payload.
SetTimerPrecision set the ticker precision, and time precision can not less than a Millisecond, and can not change after application running.
No description provided by the author
Shutdown send a signal to let 'nano' shutdown itself.
No description provided by the author

# Variables

ErrBrokenPipe represents the low-level connection has broken.
ErrBufferExceed indicates that the current session buffer is full and can not receive more data.
Errors that could be occurred during message handling.
Errors that could be occurred during message handling.
Errors that could be occurred during message handling.
Errors that could be occurred during message handling.
Errors that could be occurred during message handling.
Errors that could be occurred during message handling.
VERSION returns current nano version.

# Structs

Group represents a session group which used to manage a number of sessions, data send to the group will send to all session in it.
No description provided by the author
No description provided by the author

# Interfaces

Logger represents the log interface.
No description provided by the author
No description provided by the author
No description provided by the author

# Type aliases

No description provided by the author
No description provided by the author
SessionFilter represents a filter which was used to filter session when Multicast, the session will receive the message while filter returns true.
No description provided by the author