https://github.com/lonnng/nano/blob/master/docs/get_started_zh_CN.md
--- 文档复制于 2017-08-18,最新内容请参考最新地址----
如何构建你的第一个nano应用
在这个教程中,我们将构建一个基于浏览器和WebSocket的聊天应用。
由于游戏在场景管理、客户端动画等方面有一定的复杂性,并不适合作为nano的入门应用。对于大多数开发者
而言,普通聊天室是一个更加适合入门nano的应用。
nano是一个轻量级的服务器框架,它最适合的应用领域是网页游戏、社交游戏、移动游戏的服务端。当然还不
仅仅是游戏,用nano开发高实时 web 应用也非常合适。
前言
-
本教程适用于对
nano零基础的用户,如果你已经有过一定的nano开发基础,请跳过这个教程,你可以阅读 开发指南,那里会对一些话题作较为详细的探讨。 -
由于
nano是基于 Go 开发的,因此希望你在阅读本教程前对 Go 语言有一些了解。 -
本教程的示例源码放在 github 上完整代码
-
本教程将以一个实时聊天应用为例子,通过对这个应用进行不同的修改来展示
nano框架的一些功能特性,让用 户能大致了解nano,熟悉并能够使用nano进行应用程序的开发。 -
本教程假定你使用的开发环境是类 Unix 系统,如果你使用的 Windows 系统,希望你能够知道相关的对应方式,比 如一些.sh 脚本,在 Windows 下会使用一个同名的 bat 文件,本教程中对于 Windows 系统,不做特殊说明。
术语解释
nano有一些自己的术语,这里先对术语做一些简单的解释,给读者一个直观的概念,不至于看到相应术语时产生
迷惑。
组件(Component)
nano应用是由一些松散耦合的Component组成的,每个Component完成一些功能。整个应用可以看作是一
个Component容器,完成Component的加载以及生命周期管理。每个Component往往有Init,AfterInit,
BeforeShutdown,Shutdown等方法,用来完成生命周期管理。
type DemoComponent struct{}
func (c *DemoComponent) Init() {}
func (c *DemoComponent) AfterInit() {}
func (c *DemoComponent) BeforeShutdown() {}
func (c *DemoComponent) Shutdown() {}
Handler
Handler用来处理业务逻辑,Handler可以有如下形式的签名:
// 以下的 Handler 会自动将消息反序列化,在调用时当做参数传进来
func (c *DemoComponent) DemoHandler(s *session.Session, payload *pb.DemoPayload) error {
// 业务逻辑开始
// ...
// 业务逻辑结束
return nil
}
// 以下的 Handler 不会自动将消息反序列化,会将客户端发送过来的消息直接当作参数传进来
func (c *DemoComponent) DemoHandler(s *session.Session, raw []byte) error {
// 业务逻辑开始
// ...
// 业务逻辑结束
return nil
}
路由(Route)
route 用来标识一个具体服务或者客户端接受服务端推送消息的位置,对服务端来说,其形式一般是..,例如
"Room.Message", 在我们的示例中, Room是一个包含相关Handler的组件, Message是一个定义在
Room中的Handler, Room中所有符合Handler签名的方法都会在nano应用启动时自动注册.
对客户端来说,其路由一般形式为 onXXX(比如我们示例中的 onMessage),当服务端推送消息时,客户端会 有相应的回调。
会话(Session)
Session对应于一个客户端会话, 当客户端连接服务器后, 会建立一个会话, 会话在玩家保持连接期间可以
用于保存一些上下文信息, 这些信息会在连接断开后释放.
组(Group)
Group可以看作是一个Session的容器,主要用于需要广播推送消息的场景。可以把某个玩家的Session加
入到一个Group中,当对这个Group推送消息的时候,所有加入到这个Group的玩家都会收到推送过来的消
息。一个玩家的Session可能会被加入到多个Group中,这样玩家就会收到其加入的Group推送过来的消息。
请求(Request), 响应(Response), 通知(Notify), 推送(Push)
nano中有四种消息类型的消息,分别是请求(Request), 响应(Response), 通知(Notify)和推送(Push),客
户端发起Request到服务器端,服务器端处理后会给其返回响应Response; Notify是客户端发给服务端的
通知,也就是不需要服务端给予回复的请求; Push是服务端主动给客户端推送消息的类型。在后面的叙述中,将
会使用这些术语而不再作解释。
示例开始
Server
package main
import (
"fmt"
"log"
"net/http"
"github.com/lonnng/nano"
"github.com/lonnng/nano/component"
"github.com/lonnng/nano/serialize/json"
"github.com/lonnng/nano/session"
)
type (
// define component
Room struct {
component.Base
group *nano.Group
}
// protocol messages
UserMessage struct {
Name string `json:"name"`
Content string `json:"content"`
}
NewUser struct {
Content string `json:"content"`
}
AllMembers struct {
Members []int64 `json:"members"`
}
JoinResponse struct {
Code int `json:"code"`
Result string `json:"result"`
}
)
func NewRoom() *Room {
return &Room{
group: nano.NewGroup("room"),
}
}
func (r *Room) AfterInit() {
nano.OnSessionClosed(func(s *session.Session) {
r.group.Leave(s)
})
}
// Join room
func (r *Room) Join(s *session.Session, msg []byte) error {
s.Bind(s.ID()) // binding session uid
s.Push("onMembers", &AllMembers{Members: r.group.Members()})
// notify others
r.group.Broadcast("onNewUser", &NewUser{Content: fmt.Sprintf("New user: %d", s.ID())})
// new user join group
r.group.Add(s) // add session to group
return s.Response(&JoinResponse{Result: "sucess"})
}
// Send message
func (r *Room) Message(s *session.Session, msg *UserMessage) error {
return r.group.Broadcast("onMessage", msg)
}
func main() {
nano.Register(NewRoom())
nano.SetSerializer(json.NewSerializer())
nano.EnableDebug()
log.SetFlags(log.LstdFlags | log.Llongfile)
http.Handle("/web/", http.StripPrefix("/web/", http.FileServer( http.Dir("web"))))
nano.SetCheckOriginFunc(func(_ *http.Request) bool { return true })
nano.ListenWS(":3250")
}
- 首先, 导入这个代码片段需要应用的包
- 定义
Room组件 - 定义所有全后端交互可能用到的协议结构体(实际项目中可能使用 Protobuf)
- 定义所有的 Handler, 这里包含
Join和Message - 启动我们的应用
- 注册组件
- 设置序列化反序列器
- 开启调试信息
- 设置 log 输出信息
- Set WebSocket check origin function
- 开始监听
WebSocket地址":3250"
Client
参考各个客户端 SDK 文档
Summary
这部分, 我们构建了一个简单的聊天应用, 并对代码做了简单的介绍, 通过这个教程, 相信读者对nano的工作
流程和工作机制有了一个初步的了解.