日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

go语言游戏服务端开发(三)——服务机制

發(fā)布時(shí)間:2024/9/5 编程问答 33 如意码农
生活随笔 收集整理的這篇文章主要介紹了 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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。