go语言游戏服务端开发(三)——服务机制
生活随笔
收集整理的這篇文章主要介紹了
go语言游戏服务端开发(三)——服务机制
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
五邑隱俠,本名關(guān)健昌,12年游戲生涯。 本教程以Go語言為例。
P2P網(wǎng)絡(luò)為服務(wù)進(jìn)程間、服務(wù)進(jìn)程與客戶端間通信提供了便利,在這個(gè)基礎(chǔ)上可以搭建服務(wù)。
在服務(wù)層,通信包可以通過定義協(xié)議號來確定該包怎樣處理。每個(gè)協(xié)議號對應(yīng)一個(gè)Processor,Processor定義為一個(gè)interface
type Processor interface {
OnHandleRequest(req *Request, resp *Response) (int32, error)
}
協(xié)議號又可以拆分為模塊號和命令號。一個(gè)模塊對應(yīng)一個(gè)Service,該模塊下每個(gè)命令對應(yīng)一個(gè)Processor,通過map結(jié)構(gòu)做映射
type Service struct {
mapCmd2Processor map[uint16]Processor
}
Service提供方法添加、刪除、獲取Processor
func AddProcessor(cmd uint16, p Processor) error
func GetProcessor(cmd uint16) Processor
func RemoveProcessor(cmd uint16) error
提供個(gè)入口方法,把該模塊的Service的請求分發(fā)到對應(yīng)的Processor
func (s *Service) OnHandleRequest(req *Request, resp *Response) (int32, error) {
p, ok := s.mapCmd2Processor[req.Cmd]
if ok {
return p.OnHandleRequest(req, resp)
}
}
服務(wù) Server 是 Service 的集合,通過模塊號進(jìn)行映射
type Server struct {
mapMod2Service map[uint16]*Service
rpc *Rpc
}
同樣提供方法添加、刪除、獲取Service
func AddService(mod uint16, srv *Service) error
func GetService(mod uint16) *Service
func RemoveService(mod uint16) error
這樣當(dāng)收到一個(gè)請求包,對協(xié)議號拆分為模塊號和命令號,通過模塊號獲取到對應(yīng)的Service,調(diào)用Service的 OnHandleRequest 進(jìn)行處理
serv := s.GetService(req.Mod)
if serv != nil {
code, err := serv.OnHandleRequest(req, resp)
}
Server 基于 P2P 層,P2P的包是通用的格式,不同的游戲服務(wù)端進(jìn)程,都有可能有不同的包格式,例如,客戶端包格式和服務(wù)內(nèi)部通信的包格式是有差別的。為了讓服務(wù)通用,引入服務(wù)適配器,在請求和響應(yīng)時(shí)做預(yù)處理,轉(zhuǎn)化為通用的 Request 和 Response
type ServerAdapter interface {
OnRequest(payload []byte) (*Request, error)
OnResponse(pack *Response) ([]byte, error)
}
type Server struct {
mapMod2Service map[uint16]*Service
rpc *Rpc
adapter ServerAdapter
}
這樣在服務(wù)層都是基于 Request 和 Response進(jìn)行處理,由具體業(yè)務(wù)對業(yè)務(wù)包做轉(zhuǎn)換
type Request struct {
Mod uint16
Cmd uint16
Payload []byte
}
type Response struct {
Mod uint16
Cmd uint16
Payload []byte
}
服務(wù) Server 還可以提供攔截器,攔截器的好處是對一些階段進(jìn)行統(tǒng)一處理,而且可以通過插入新攔截器進(jìn)行擴(kuò)展,隨時(shí)都可以替換這個(gè)階段的邏輯(例如從 json 包變成 proto 包、增加二進(jìn)制頭等),攔截器可以針對3個(gè)階段: 請求處理前,請求處理后,響應(yīng)發(fā)送后
type Interceptor interface {
OnPreHandle(req *Request, resp *Response) (int32, error)
OnHandleCompletion(req *Request, resp *Response) (int32, error)
OnResponseCompletion(req *Request, resp *Response) error
}
除了全局?jǐn)r截器,還可以添加針對某個(gè)模塊 Service 的攔截器,對某個(gè) Service 做特殊攔截處理
type InterceptorList []Interceptor
type Server struct {
mapMod2Service map[uint16]*Service
rpc *Rpc
adapter ServerAdapter
globalInterceptors InterceptorList
mapMod2Interceptors map[uint16]InterceptorList
}
這樣一個(gè)請求的處理過程就變成
// adapter
req, err := s.adapter.OnRequest(payload)
resp := NewResponse(req)
// prehandle
interList, ok := s.mapMod2Interceptors[req.Mod]
s.prehandle(interList, ok, req, resp)
// handle
serv := s.GetService(req.Mod)
code, err := serv.OnHandleRequest(req, resp)
// handle complete
s.handleCompletion(interList, ok, req, resp)
s.push(resp)
// response complete
s.responseCompletion(interList, ok, req, resp)
服務(wù)機(jī)制介紹到這里,接下來聊聊 RPC 機(jī)制
總結(jié)
以上是生活随笔為你收集整理的go语言游戏服务端开发(三)——服务机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Resize image online
- 下一篇: 递归算法之不用乘号的乘法——用位移实现乘