
正文
go语言rpc处理流程 go语言rpc框架
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
如何实现 JavaScript RPC 应用
如何实现 JavaScript RPC 应用
作者:谢声涛
一、一个 JavaScript RPC 的实现
1、RPC工作流程
JavaScript RPC 的简单实现过程是:
在客户端JavaScript脚本中,将要调用的服务端PHP函数名和函数参数(本地的JavaScript变量值)作为要传输的数据,通过Ajax传输到服务端,同时,Ajax设置一个回调函数,以便使用服务端函数的返回结果。在服务端PHP脚本中,接收Ajax传输的数据,从中取出要执行的函数名和函数参数。然后执行指定的函数,并将执行函数的返回值作为传输的数据,直接输出到浏览器,以此作为响应AJax的请求。客户端的Ajax在接受服务端的响应后,把返回的数据传递给AJax的回调函数。到此完成了一个RPC的流程。
2、传输的数据
在RPC执行过程中,客户端与服务端需要相互传输数据,我们分别称之为客户端数据和服务端数据。对此的说明如下表:
客户端数据:
函数名:服务端PHP脚本中存在的函数。
函数参数:客户端JavaScript脚本中的变量值。
服务端数据:
函数返回值:执行服务端PHP函数的返回值。
3、序列化与反序列化
为了要传输客户端的变量值和服务端的函数返回值,需要对其进行序列化处理。与之相对应的在传输后还要进行反序列化处理。
JavaScript中的变量的类型:基本类型和JSON类型(普通数组、元对象)
PHP中的变量类型:基本类型和数组(普通数组和关联索引数组)
PHP语言具有序列化和反序列化函数,而JavaScript语言中没有,因此我们要自己实现它。
由于我们进行JavaScript和PHP之间的数据交换,所以直接把JavaScript变量序列化为PHP的序列化形式。我们实现Js2PhpSerialize函数来完成这个任务。
Js2PhpSerialize:主要是把JSON对象及嵌套调用的JSON对象和基本类型的数据表示为PHP的序列化形式。
服务端的PHP在执行函数后,把结果序列化为JavaScript能理解的形式,以便于eval动态生成变量。我们实现php2JsSerialize函数来完成这个任务。
4、功能实现
我们创建两个类来完成上述功能。一个是客户端的JavaScript类,一个是服务端的PHP类。
文件名:jsrpc.class.js
要实现的功能: A、序列化JavaScript的数据。 B、Ajax传输序列化数据 C、反序列化JavaScript数据。 D、设置回调函数。
文件名:jsrpc.class.php
要实现的功能: A、响应Ajax请求,接收序列化数据。 B、反序列化PHP数据,基本类型和数组。 C、序列化PHP数据为JavaScript数据。
将JavaScript的数据类型转换为PHP可以理解的形式,通过Ajax把转换后的数据传递到服务端,由PHP的eval函数解析为PHP的数据类型。
PHP函数执行后,将执行结果数据转换为JavaScript可以理解的形式,由Ajax的回调函数响应,并由JavaScript的eval函数解析为JavaScript的数据类型。
二、应用示例
代码片段:
JavaScript端:
SCRIPT language=javascript src="jsrpc.class.js"/SCRIPT
SCRIPT language=javascript
var arr = new Array(1,'abc', new Array(3,'xyz'),5);
var rpc = new JsRPC();
rpc.call('ajax_server.php', 'checkBook', response, arr);
function response(result) {
alert(result[1]);
}
/SCRIPT
PHP端(即文件ajax_server.php):
?php
require_once('jsrpc.class.php');
$ar = new JsRPC();
$ar-register('checkBook');
$ar-start();
function checkBook($param) {
return $param;
}
?
如上所示,它使用方法与一个叫CPaint的类库相似,只是省去了将数据装到一个对象中的步骤。
三、获取源码
相关问答
Q1: 一学就会,手把手教你用Go语言调用智能合约
智能合约调用是实现一个 DApp go语言rpc处理流程的关键go语言rpc处理流程,一个完整go语言rpc处理流程的 DApp 包括前端、后端、智能合约及区块 链系统,智能合约go语言rpc处理流程的调用是连接区块链与前后端的关键。
我们先来了解一下智能合约调用的基础原理。智能合约运行在以太坊节点的 EVM 中。因此要 想调用合约必须要访问某个节点。
以后端程序为例,后端服务若想连接节点有两种可能,一种是双 方在同一主机,此时后端连接节点可以采用 本地 IPC(Inter-Process Communication,进 程间通信)机制,也可以采用 RPC(Remote Procedure Call,远程过程调用)机制;另 一种情况是双方不在同一台主机,此时只能采用 RPC 机制进行通信。
提到 RPC, 读者应该对 Geth 启动参数有点印象,Geth 启动时可以选择开启 RPC 服务,对应的 默认服务端口是 8545。。
接着,我们来了解一下智能合约运行的过程。
智能合约的运行过程是后端服务连接某节点,将 智能合约的调用(交易)发送给节点,节点在验证了交易的合法性后进行全网广播,被矿工打包到 区块中代表此交易得到确认,至此交易才算完成。
就像数据库一样,每个区块链平台都会提供主流 开发语言的 SDK(Software Development Kit,软件开发工具包),由于 Geth 本身就是用 Go 语言 编写的,因此若想使用 Go 语言连接节点、发交易,直接在工程内导入 go-ethereum(Geth 源码) 包就可以了,剩下的问题就是流程和 API 的事情了。
总结一下,智能合约被调用的两个关键点是节点和 SDK。
由于 IPC 要求后端与节点必须在同一主机,所以很多时候开发者都会采用 RPC 模式。除了 RPC,以太坊也为开发者提供了 json- rpc 接口,本文就不展开讨论了。
接下来介绍如何使用 Go 语言,借助 go-ethereum 源码库来实现智能合约的调用。这是有固定 步骤的,我们先来说一下总体步骤,以下面的合约为例。
步骤 01:编译合约,获取合约 ABI(Application Binary Interface,应用二进制接口)。 单击【ABI】按钮拷贝合约 ABI 信息,将其粘贴到文件 calldemo.abi 中(可使用 Go 语言IDE 创建该文件,文件名可自定义,后缀最好使用 abi)。
最好能将 calldemo.abi 单独保存在一个目录下,输入“ls”命令只能看到 calldemo.abi 文件,参 考效果如下:
步骤 02:获得合约地址。注意要将合约部署到 Geth 节点。因此 Environment 选择为 Web3 Provider。
在【Environment】选项框中选择“Web3 Provider”,然后单击【Deploy】按钮。
部署后,获得合约地址为:0xa09209c28AEf59a4653b905792a9a910E78E7407。
步骤 03:利用 abigen 工具(Geth 工具包内的可执行程序)编译智能合约为 Go 代码。abigen 工具的作用是将 abi 文件转换为 Go 代码,命令如下:
其中各参数的含义如下。 (1)abi:是指定传入的 abi 文件。 (2)type:是指定输出文件中的基本结构类型。 (3)pkg:指定输出文件 package 名称。 (4)out:指定输出文件名。 执行后,将在代码目录下看到 funcdemo.go 文件,读者可以打开该文件欣赏一下,注意不要修改它。
步骤 04:创建 main.go,填入如下代码。 注意代码中 HexToAddress 函数内要传入该合约部署后的地址,此地址在步骤 01 中获得。
步骤 04:设置 go mod,以便工程自动识别。
前面有所提及,若要使用 Go 语言调用智能合约,需要下载 go-ethereum 工程,可以使用下面 的指令:
该指令会自动将 go-ethereum 下载到“$GOPATH/src/github.com/ethereum/go-ethereum”,这样还算 不错。不过,Go 语言自 1.11 版本后,增加了 module 管理工程的模式。只要设置好了 go mod,下载 依赖工程的事情就不必关心了。
接下来设置 module 生效和 GOPROXY,命令如下:
在项目工程内,执行初始化,calldemo 可以自定义名称。
步骤 05:运行代码。执行代码,将看到下面的效果,以及最终输出的 2020。
上述输出信息中,可以看到 Go 语言会自动下载依赖文件,这就是 go mod 的神奇之处。看到 2020,相信读者也知道运行结果是正确的了。
Q2: rpc的实现机制是什么
RPC 的全称是 Remote Procedure Call 是一种进程间通信方式。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即无论是调用本地接口/服务的还是远程的接口/服务,本质上编写的调用代码基本相同。
比如两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数或者方法,由于不在一个内存空间,不能直接调用,这时候需要通过就可以应用RPC框架的实现来解决。
RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)
RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)
RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。
二、常见RPC框架
几种比较典型的RPC的实现和调用框架。
(1)RMI实现,利用java.rmi包实现,基于Java远程方法协议(Java Remote Method Protocol)
和java的原生序列化。
(2)Hessian,是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能。 基于HTTP协议,采用二进制编解码。
(3)THRIFT是一种可伸缩的跨语言服务的软件框架。thrift允许你定义一个描述文件,描述数据类型和服务接口。依据该文件,编译器方便地生成RPC客户端和服务器通信代码。
二、RPC框架实现原理
在RPC框架中主要有三个角色:Provider、Consumer和Registry。如下图所示:
RPC框架面试总结-RPC原理及实现
节点角色说明:
* Server: 暴露服务的服务提供方。
* Client: 调用远程服务的服务消费方。
* Registry: 服务注册与发现的注册中心。
三、RPC调用流程
RPC基本流程图:
RPC框架面试总结-RPC原理及实现
一次完整的RPC调用流程(同步调用,异步另说)如下:
1)服务消费方(client)调用以本地调用方式调用服务;
2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
3)client stub找到服务地址,并将消息发送到服务端;
4)server stub收到消息后进行解码;
5)server stub根据解码结果调用本地的服务;
6)本地服务执行并将结果返回给server stub;
7)server stub将返回结果打包成消息并发送至消费方;
8)client stub接收到消息,并进行解码;
9)服务消费方得到最终结果。
RPC框架的目标就是要2~8这些步骤都封装起来,让用户对这些细节透明。
四、服务注册发现
RPC框架面试总结-RPC原理及实现
服务提供者启动后主动向注册中心注册机器ip、port以及提供的服务列表;
服务消费者启动时向注册中心获取服务提供方地址列表,可实现软负载均衡和Failover;
五、使用到的技术
1、动态代理
生成 client stub和server stub需要用到 Java 动态代理技术 ,我们可以使用JDK原生的动态代理机制,可以使用一些开源字节码工具框架 如:CgLib、Javassist等。
2、序列化
为了能在网络上传输和接收 Java对象,我们需要对它进行 序列化和反序列化操作。
* 序列化:将Java对象转换成byte[]的过程,也就是编码的过程;
* 反序列化:将byte[]转换成Java对象的过程;
可以使用Java原生的序列化机制,但是效率非常低,推荐使用一些开源的、成熟的序列化技术,例如:protobuf、Thrift、hessian、Kryo、Msgpack
关于序列化工具性能比较可以参考:jvm-serializers
3、NIO
当前很多RPC框架都直接基于netty这一IO通信框架,比如阿里巴巴的HSF、dubbo,Hadoop Avro,推荐使用Netty 作为底层通信框架。
4、服务注册中心
可选技术:
* Redis
* Zookeeper
* Consul
* Etcd
go语言rpc处理流程的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于go语言rpc框架、go语言rpc处理流程的信息别忘了在本站进行查找喔。







