游戏编程系列[1]--游戏编程中RPC协议的使用

RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。

首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。

以上摘自,百度百科。

第一个问题是Why?通过一个特定协议定义,我们可以脱离常规的协议定义。使用一个通用协议来达到远程调用的过程。
   第二个问题协议?我们选择的是Json协议,好处就是灵活多变,可以使用一个字符串表示所有对象。
      坏处就是解析略慢,因为没有长度标识,所以不能搜索,只能一次性解析。不过在于交换场景,这个一点问题都没。

这里是协议定义:

请求定义:

    public partial class RequestObj
    {
        /// <summary>
        /// 命令(一般为方法名称)
        /// </summary>
        public string cmd { get; set; }

        /// <summary>
        /// 名字空间
        /// </summary>
        public string ns { get; set; }

        /// <summary>
        /// 参数
        /// </summary>
        public object[] args { get; set; }

        /// <summary>
        /// 请求序号
        /// </summary>
        public int cid { get; set; }

        /// <summary>
        /// 如果WebSocket才使用
        /// </summary>
        public string tk { get; set; }

        /// <summary>
        /// 主动版本同步,0则忽略
        /// </summary>
        public int ver { get; set; }

	}

响应定位:

  /// <summary>
    /// 返回数据
    /// </summary>
    public partial class ResponseObj
    {
        /// <summary>
        /// 返回数据对象
        /// </summary>
        public object result { get; set; }

        /// <summary>
        /// 是否出错信息
        /// 默认0 无出错信息
        /// </summary>
        public int error { get; set; }

        /// <summary>
        /// 请求序号
        /// </summary>
        public int cid { get; set; }

        /// <summary>
        /// 差异数据
        /// </summary>
        public OpChangeItem[] opstr{ get; set; }

    }

疑问:
object,这是一个不科学的设定?这边待保留。
OpChangeItem,这个是什么鬼?依然保留。

这里我们尝试来进行一次调用构造。

特定方法:

	public class LocalTest
	{
			/// <summary>
			/// 添加一个消息
			/// </summary>
			public static void AddMessage(string topic, string messageBody)
			{
				//这里什么都不干
			}
	}

发送消息:

{"args":["Test","Message"],"cid":"1","cmd":"AddMessage","ns":"LocalTest","tk":null}

从以上我们可以解析出来

类名:LocalTest, 调用方法名:AddMessage,参数[topic : Test , messageBody:Message]

通过反射调用,我们就完成了执行的目的。

然后是返回值:

调用完成后,返回消息:

{"result": null , "error" : 0 ,"cid" : 1, "opstr":[] }

注:cid的设定是为了区分调用的请求源,如果你有多个调用同时发起,那么cid拿来区分你的来源,从而达到返回值的匹配。

从以上例子看出,我们调用了一个AddMessage方法,服务端进行了响应,然后什么事情都没发生。

我们这里的协议,抛开Opstr字段已经可以完整的描述一整个调用,因为返回值,和参数都用的object,
所以只要知道类型,那么可以通过json转换成对应的参数和类型,所以我们无需特别约定协议即可以得到特定的类型。

然后我们进行修改

		public void AddMessage(string topic, string messageBody,Action callback)
        {
            try
            {
				//这边进行一次封装,直接把当前的方法调用包装成请求,然后通过标记,判是否是本地执行,
				//如果是本地执行,则执行本地
                var __cid = WindNet.RemoteCall.Instance.DoCall(callback, this, "LocalTest.AddMessage", topic,messageBody);
                if (WindNet.RemoteCall.Instance.IsLocal || __cid.isLocal)
                {
				   //原本执行的事情
                   //这里什么都不干
				   if(callback!=null)
						callback();
                }
				//如果是远程调用,则什么都不干。
            }
            catch (Exception)
            {
                WindNet.RemoteCall.Instance.DoError(e);
				throw;
            }
        }

  

首先我们加了个callback参数,当执行完毕之后,我们调用一下callback
因为网络是一个不稳定的玩意,如果你一直在等待,则可能卡住主线程,在游戏中你的渲染就无法进行,那么我们使用callback来进行流程处理。
以及返回值的处理。
流程就是这样,你调用函数-》构造请求-》发起请求-》 服务器返回后-》调用callbak
如果我们把IsLocal 设为true
流程就是
你调用函数-》构造请求(不发出)-》执行本地方法-》执行callback

经过我们的设计,我们在执行函数前进行了一次简单的拦截,然后通过通用协议和cid进行callback的匹配,然后达到正确的回调过程。

时间: 2025-01-01 20:35:53

游戏编程系列[1]--游戏编程中RPC协议的使用的相关文章

Hadoop中RPC协议小例子报错java.lang.reflect.UndeclaredThrowableException解决方法

最近在学习传智播客吴超老师的Hadoop视频,里面他在讲解RPC通信原理的过程中给了一个RPC的小例子,但是自己编写的过程中遇到一个小错误,整理如下: log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).log4j:WARN Please initialize the log4j system properly.log4j:WARN See

【浅墨Unity3D Shader编程】之一 游戏场景的创建 &amp; 第一个Shader的书写

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 作为一个系统介绍Unity3D中Shader编写的系列文章的开篇,本文的第一部分系列文章的前言,然后第二部分介绍了这个系列文章中我们会使用的游戏场景创建方式,最后一部分讲解了如何在Un

【读书笔记《Android游戏编程之从零开始》】20.游戏开发基础(游戏数据存储)

对于数据的存储,Android 提供了4种保存方式. (1)SharedPreference 此方法适用于简单数据的保持,文如其名,属于配置性质的保存,不适合比较大的情况,默认存放在手机内存里 (2)FileInputStream/FileOutputStream 此方式比较适合游戏的保存和使用,流文件数据存储可以保持较大的数据,而且通过此方式不仅能把数据存储在手机内存中,也能将数据保存到手机额SDcard中. (3)SQLite 此方式也适合游戏的保存和使用,不仅可以保存较大的数据,而且可以将

结对编程————黄金点游戏

一.项目描述:黄金点游戏 黄金点游戏是一个数字小游戏,其游戏规则是: N个同学(N通常大于10),每人写一个0-100之间的有理数 (不包括0或100),交给裁判,裁判算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数),得到G值.提交的数字最靠近G(取绝对值)的同学得到N分,离G最远的同学得到-2分,其他同学得0分.玩了几天以后,大家发现了一些很有意思的现象,比如黄金点在逐渐地往下移动. 现在请大家根据这个游戏规则,编一个可以多人一起玩的小游戏程序,要求如下: 1.本作业属于结对编程项

结对编程——黄金点游戏之旅【二】

一.黄金点游戏是一个数字小游戏,其游戏规则是: N个同学(N通常大于10),每人写一个0-100之间的有理数(不包括0或100),交给裁判,裁判算出所有数字的平均值,然后乘以0.618(黄金分割常数),得到G值.提交的数字最靠近G(取绝对值)的同学得到N分,离G最远的同学得到-2分,其他同学得0分. 二.后续功能的实现功能 经过三天的努力,我们终于完成了开始游戏.取消准备.查看历史纪录.添加测试以及退出登录功能. 1.开始游戏(准备游戏)功能介绍:玩家登陆成功后直接进入游戏界面,下方的准备窗口会

结对编程-黄金点游戏之旅[四]

(游戏已上线,更多信息请戳底部链接▼) <--戳这个链接也会跳的哦, 了解游戏规则戳这里-->游戏规则 我的队友: 张波(进入博客请戳底部链接) 性格开朗,人很随和,不想写代码的时候都是他主动拉着我去写的,工作认真负责,有分歧的地方或者逻辑不顺的地方我们都会仔细讨论 主要负责写后台的业务逻辑,登陆.注册.开始游戏等小功能的后台代码 遵照代码规范.每次他写完后我都会做Code Review,虽然没有自动化测试,没有性能分析,但是我会单步调试,分析每一行代码的逻辑和作用 我: 李洋洋 主要负责前端

Scratch克隆应用编程之射击游戏

一.引言 在我的上一篇文章 https://blog.51cto.com/zhuxianzhong/2474435 <Scratch高级编程之克隆技术再研究>中,我把Scratch的克隆技术划分为非共享数据克隆体与共享数据克隆体两大类型,本文将给出非共享数据克隆体的一种应用举例--克隆子弹与弹壳.当然,这个例子属于克隆技术的一种比较基础性的应用情形. 二.快照欣赏 因为本处不方便提供视频片断,仅提供游戏过程中枪发射子弹某一时刻的静态截图如下: 三.角色功能设计 (一)小游戏中几个关键角色的关系

.net中的并行编程系列-1.基础知识

最近半年一直研究用.net进行并行程序的开发与设计,再研究的过程中颇有收获,所以画了一个图总结了一下并行编程的基础知识点,这些知识点是并行编程的基础,有助于我们编程高性能的程序,里面的某些结构实现机制也蕴含着丰富的软件设计思想,在后续的文章中我会对图里面提到某些数据结构或同步机制的源码进行分析. 注:虽然使用的平台是.net ,但大部分知识点和平台以及语言无关,相关数据结构其他相关平台都有实现,包括优化手段都非常相似. .net中的并行编程系列-1.基础知识,布布扣,bubuko.com

七、考反映小游戏《苹果iOS实例编程入门教程》

该app为应用的功能为一个简单的考反应游戏 纲要:-UIButton, UILabel, UIImageView 的运用:-利用rendom增加游戏可玩性: 游戏说明: 在按下开始游戏后,分为三盏的指示灯按照“黄”.“红”.“绿”的先后顺序各自读取相应的指示灯颜色图片文件,当黄灯亮后游戏使用随机变量产生没有规律的红灯持续时间,因为这样的红灯使玩家没法预计绿灯什么时候亮,所以按下油门的时间要看玩家的反应速度,油门按下后,游戏会把从绿灯亮起直到玩家按下油门之间所使用的时间显示新窗口,并且提示玩家时候