五邑隐侠,本名关健昌,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调用介绍到这里。接下来介绍下游戏业务进程的实现。
 

go语言游戏服务端开发(四)——RPC机制的更多相关文章

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

    五邑隐侠,本名关健昌,12年游戏生涯. 本教程以Go语言为例.   P2P网络为服务进程间.服务进程与客户端间通信提供了便利,在这个基础上可以搭建服务. 在服务层,通信包可以通过定义协议号来确定该包怎 ...

  2. go语言游戏服务端开发(二)——网络通信

    一.网络层 网络游戏客户端除了全局登录使用http请求外,一般通过socket长连接与服务端保持连接.go语言的net包提供网络socket长连接相关操作. 对于服务端,一般经历 Listen.Acc ...

  3. go语言游戏服务端开发(一)——架构

    五邑隐侠,本名关健昌,12年游戏生涯. 本教程以Go语言为例.   网络游戏程序分为客户端和服务端.客户端负责图形渲染.交互和一些简单校验处理,服务端负责业务逻辑处理.数据存储. 我们开发一个游戏de ...

  4. Swift3.0服务端开发(四) MySQL数据库的连接与操作

    本篇博客我们来聊聊MySQL数据库的连接与操作.如果你本地没有MySQL数据库的话,需要你先安装MySQL数据库.在Mac OS中使用brew包管理器进行MySQL的安装是及其方便的.安装MySQL的 ...

  5. Swift3.0服务端开发(五) 记事本的开发(iOS端+服务端)

    前边以及陆陆续续的介绍了使用Swift3.0开发的服务端应用程序的Perfect框架.本篇博客就做一个阶段性的总结,做一个完整的实例,其实这个实例在<Swift3.0服务端开发(一)>这篇 ...

  6. 转: 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端

    from: http://ybak.iteye.com/blog/1853335 基于netty+ protobuf +spring + hibernate + jgroups开发的游戏服务端 游戏服 ...

  7. 俯瞰 Java 服务端开发

    原文首发于 github ,欢迎 star . Java 服务端开发是一个非常宽广的领域,要概括其全貌,即使是几本书也讲不完,该文将会提到许多的技术及工具,但不会深入去讲解,旨在以一个俯瞰的视角去探寻 ...

  8. 为什么多数游戏服务端是用 C++ 来写

    早年开发游戏必须用C++,这没得说,2000-2004年,java还没有nio,其他动态语言不抗重负,只能C/C++能开发出完整可用的游戏服务端.直到2005年,韩国的游戏很多都还是纯C++写服务端, ...

  9. 游戏服务端pomelo完整安装配置过程

    版权声明:本文为博主原创文章,转载或又一次发表请先与我联系. https://blog.csdn.net/jonahzheng/article/details/27658985 游戏服务端pomelo ...

随机推荐

  1. protected访问权限

    Java中protected方法访问权限的问题 protected 修饰的成员变量或方法,只能在同包或子类可访问; package 1 public class TestPackage { prote ...

  2. 【MATLAB】常用命令快速入门,国赛加油

    矩阵运算 矩阵的基本生成 m1 = 1:5 % 生成行矩阵[1,2,3,4,5] m2 = 1:2:10 % 起点:步长:终点 [1,3,5,7,9] linspace(x1,x2,n) % 生成 n ...

  3. 在C++中使用openmp进行多线程编程

    在C++中使用openmp进行多线程编程 一.前言 多线程在实际的编程中的重要性不言而喻.对于C++而言,当我们需要使用多线程时,可以使用boost::thread库或者自从C++ 11开始支持的st ...

  4. 关于notepad++使用的那些事儿

    时间:2019-04-11 整理:PangYuaner 标题:Notepad++正则表达式语法 地址:https://www.cnblogs.com/kekec/p/5255475.html 标题:N ...

  5. 已知三角形ABC为锐角三角形,求 sinA + sinB·sin(C/2) 的最大值。

    已知三角形ABC为锐角三角形,求 sinA + sinBsin(C/2) 的最大值. 解:Δ := sinA + sinB·sin(C/2) = sin(B+C) + sinB·sin(C/2) = ...

  6. 图解最长回文子串「Manacher 算法」,基础思路感性上的解析

    问题描述: 给你一个字符串 s,找到 s 中最长的回文子串. 链接:https://leetcode-cn.com/problems/longest-palindromic-substring 「Ma ...

  7. Jenkins手动下载并安装插件

    最近遇到Jenkins插件无法自动安装的问题,在插件管理页面的[升级站点]使用镜像url也无法解决.于是决定手动下载并安装Jenkins插件,具体步骤如下. Step1:进入Jenkins官网的插件下 ...

  8. kubernetes使用jenkins Pipeline 部署Nginx

    文章原文 环境需求 kubernetes 未安装参考使用kubeadm安装kubernetes 1.21 jenkins github/gitee/gitlab 静态页面 镜像仓库(我使用的 hub. ...

  9. TOMCAT WEB请求乱码

    post乱码: 原因: ​ 对于POST方式,它采用的编码是由页面来决定的即ContentType("text/html; charset=GBK").当通过点击页面的submit ...

  10. go语言调用everything的SDK接口

    介绍 官方SDK地址 本项目会将官方dll编译到可执行程序中,运行时无需考虑dll问题. 根据官方介绍,使用SDK前需要运行everything程序. 执行go build -tag ASCII时编译 ...