zoukankan      html  css  js  c++  java
  • go语言游戏服务端开发(四)——RPC机制

    五邑隐侠,本名关健昌,12年游戏生涯。 本教程以Go语言为例。

    RPC指远程方法调用,游戏里引入RPC目的是降低跨进程交互的复杂度。
    游戏业务设计为多go routine,一个玩家一个go routine。游戏里RPC客户端阻塞式调用远程(服务进程)方法,这样处理的好处是跨进程交互的业务也可以按照单线程顺序执行的思路实现。
    RPC请求包由以下几部分组成:标记(字符串,用于区分是哪类调用)、序列号(一次调用的唯一标记)、方法编号(用于映射调用的方法)、参数。
    RPC响应包由以下几部分组成:标记、序列号、方法编号、返回值。
    type RpcRequest struct {
        Mark      []byte
        FuncNo    uint16
        SerialNo  uint16
        Params    []byte
    }
    
    type RpcResponse struct {
        Mark      []byte
        FuncNo    uint16
        SerialNo  uint16
        ReturnVal    []byte
    }
    RPC建立在P2P网络之上,在 P2pListener interface 的 OnP2pCall(p2p *P2pNet, pack *P2pPack) 实现方法,根据包头前几个字节与 Mark 对比,如果一致则调用对应的RPC客户端/服务端进行处理。
    对于RPC服务,可以参考http服务,建立方法编号到处理方法的映射。
    type RpcHandler func(params []byte) ([]byte, error)
    
    type RpcServ struct {
        p2p               *P2pNet
        mark              []byte
        mapFuncNo2Handler map[uint16]RpcHandler
    }
    
    func (s *RpcServ) HandleFunc(funcNo uint16, handler func(params []byte) ([]byte, error)) {
        if handler == nil {
            return
        }
        s.mapFuncNo2Handler[funcNo] 
    = handler }
    当收到请求后,解析出funcNo和参数Params,调用对应的处理器进行处理。
    handler, ok := s.mapFuncNo2Handler[rpc.FuncNo]
    if !ok {
        return fmt.Errorf("no handler for funcNo %d", rpc.FuncNo)
    }
    returnVal, err :
    = handler(rpc.Params)
    RPC服务对请求的处理可以是非阻塞的。
    一般只对RPC客户端做成阻塞的,这样在客户端调用远程方法时,客户端会一直等待服务端返回才继续往下执行,整个逻辑流程跟单线程执行一样。
    通过序列号SerialNo、方法号 FuncNo 双重确认响应包对应于当前请求。
    在go语言里,可以通过定义一个长度为1的 chan byte,请求发出后,读取通道,如果还没有收到响应就会阻塞,响应返回时往通道里写个1,唤醒调用流程继续执行。
    func Wait(e chan byte) {
        <-e
    }
    func Signal(e chan byte) {
        e <- 1
    }
    调用方法的参数和返回值都是二进制,业务可以根据自己的需要用json或 protobuff 进行序列化/反序列化。
    func (c *RpcClient) invoke(params []byte) ([]byte, error)
    RPC调用介绍到这里。接下来介绍下游戏业务进程的实现。
     
  • 相关阅读:
    SQL Server 之 在与SQLServer建立连接时出现与网络相关的或特定于实例的错误的解决方法
    Exchange学习:EWS 通过流通知和拉取通知订阅Exchange新邮件提醒
    拓扑提供程序在端点TopologyClientTcpEndpoint (localhost) 上找不到microsoft exchange active directory拓扑服务的解决办法之一
    解决vs下载速度慢或者无法下载,无法下载.net sdk的解决办法
    记一个List转List<Object>的方法
    SqlServer数据库存入decimal类型数据注意事项
    如何在vs里面查看方法重载
    LeetCode 198. 打家劫舍 Java
    LeetCode面试题53
    LeetCode 1010. 总持续时间可被 60 整除的歌曲 Java
  • 原文地址:https://www.cnblogs.com/niudanshui/p/15381267.html
Copyright © 2011-2022 走看看