由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 :  --> 点击这里

  RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。
百度中有很多种解释,但根据公司所用的,以下解释比较贴切:
        首先,要解决通讯的问题,主要是通过在客户端和服务器之间建立TCP连接,远程过程调用的所有交换的数据都在这个连接里传输。连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远程过程调用共享同一个连接。
        第二,要解决寻址的问题,也就是说,A服务器上的应用怎么告诉底层的RPC框架,如何连接到B服务器(如主机或IP地址)以及特定的端口,方法的名称名称是什么,这样才能完成调用。比如基于Web服务协议栈的RPC,就要提供一个endpoint URI,或者是从UDDI服务上查找。如果是RMI调用的话,还需要一个RMI Registry来注册服务的地址。
        第三,当A服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如TCP传递到B服务器,由于网络协议是基于二进制的,内存中的参数的值要序列化成二进制的形式,也就是序列化(Serialize)或编组(marshal),通过寻址和传输将序列化的二进制发送给B服务器。
        第四,B服务器收到请求后,需要对参数进行反序列化(序列化的逆操作),恢复为内存中的表达方式,然后找到对应的方法(寻址的一部分)进行本地调用,然后得到返回值。
        第五,返回值还要发送回服务器A上的应用,也要经过序列化的方式发送,服务器A接到后,再反序列化,恢复为内存中的表达方式,交给A服务器上的应用

公司所用的是客户端为php,服务端为lua。


举例(只是两个简单的示例,实际项目比较复杂):

服务端示例:

<?php
class RpcServer {
protected $serv = null; public function __construct($host, $port, $path) {
//创建一个tcp socket服务
$this->serv = stream_socket_server("tcp://{$host}:{$port}", $errno, $errstr);
if (!$this->serv) {
exit("one {$errno} : {$errstr} \n");
}
//判断我们的RPC服务目录是否存在
$realPath = realpath(__DIR__ . $path); if ($realPath === false || !file_exists($realPath)) {
exit("two {$path} error \n");
} while (true) {
$client = stream_socket_accept($this->serv); if ($client) {
//这里为了简单,我们一次性读取
$buf = fread($client, );
//解析客户端发送过来的协议
$classRet = preg_match('/Rpc-Class:\s(.*);\r\n/i', $buf, $class);
$methodRet = preg_match('/Rpc-Method:\s(.*);\r\n/i', $buf, $method);
$paramsRet = preg_match('/Rpc-Params:\s(.*);\r\n/i', $buf, $params); if($classRet && $methodRet) {
$class = ucfirst($class[]);
$file = $realPath . '/' . $class . '.php';
//判断文件是否存在,如果有,则引入文件
if(file_exists($file)) {
require_once $file;
//实例化类,并调用客户端指定的方法
$obj = new $class();
//如果有参数,则传入指定参数
if(!$paramsRet) {
$data = $obj->$method[]();
} else {
$data = $obj->$method[](json_decode($params[], true));
}
//把运行后的结果返回给客户端
fwrite($client, $data);
}
} else {
fwrite($client, 'class or method error' . $classRet . '-' . $methodRet);
}
//关闭客户端
fclose($client);
}
}
} public function __destruct() {
fclose($this->serv);
}
} new RpcServer('127.0.0.1', , '/service');

客户端举例:

<?php

class RpcClient {
protected $urlInfo = array(); public function __construct($url) {
//解析URL
$this->urlInfo = parse_url($url);
if(!$this->urlInfo) {
exit("{$url} error \n");
}
} public function __call($method, $params) {
//创建一个客户端
$client = stream_socket_client("tcp://{$this->urlInfo['host']}:{$this->urlInfo['port']}", $errno, $errstr);
if (!$client) {
exit("{$errno} : {$errstr} \n");
}
//传递调用的类名
$class = basename($this->urlInfo['path']);
$proto = "Rpc-Class: {$class};" . 'Say';
//传递调用的方法名
$proto .= "Rpc-Method: {$method};" . 'hello';
//传递方法的参数
$params = json_encode($params);
$proto .= "Rpc-Params: {$params};" . PHP_EOL;
//向服务端发送我们自定义的协议数据
fwrite($client, $proto);
//读取服务端传来的数据
$data = fread($client, );
//关闭客户端
fclose($client);
return $data;
}
} $cli = new RpcClient('http://127.0.0.1:8888/test');
echo $cli->hehe();
echo $cli->hehe2(array('name' => 'test', 'age' => ));

先启动服务端,再启动客户端

 

 

RPC 简单小试的更多相关文章

  1. 【转】RPC简单介绍

    RPC简单介绍 RPC 1. RPC是什么 RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络 ...

  2. 分布式系统间通信之RPC简单Demo(七)

    看似终点,回到起点.第一次接触C#,编写的第一个真正的Demo是基于Socket的简单通信,现在JAVA开始的第一个RPC的Demo也是基于Socket.. 下面通过java原生的序列化,Socket ...

  3. Hadoop之RPC简单使用(远程过程调用协议)

    一.RPC概述 RPC是指远程过程调用,也就是说两台不同的服务器(不受操作系统限制),一个应用部署在Linux-A上,一个应用部署在Windows-B或Linux-B上,若A想要调用B上的某个方法me ...

  4. Hadoop RPC简单例子

    jdk中已经提供了一个RPC框架-RMI,但是该PRC框架过于重量级并且可控之处比较少,所以Hadoop RPC实现了自定义的PRC框架. 同其他RPC框架一样,Hadoop RPC分为四个部分: ( ...

  5. 分布式通讯架构RPC简单实现

    什么是RPC: RPC(Remote Procedure Call,远程过程调用),一般用来实现部署在不同机器上的系统之间的方法调用,使得程序能够像访问本地系统资源一样,通过网络传输去访问远端系统资源 ...

  6. Rpc简单入门

    RPC这个概念大家都应该很熟悉了,这里不在累述了:使用场景可以参考这篇,本篇主要分享下Thrift和Grpc在.Net Core环境下使用入门.Thirft或者Grps 都支持跨语言.跨平台的Rpc框 ...

  7. php实现rpc简单的方法

    rpc是啥这不多解释,php扩展实现rpc yar是鸟哥的写的扩展,实现简单的rpc.比较很好理解 windows安装yar http://pecl.php.net/package/yar/2.0.4 ...

  8. RPC简单设计方案

    服务端: 启动后,等待客户端发来信息,收到信息后进行处理,返回结果. 客户端: 主线程中发起一次RPC,那么就将信息封装成一个任务,提交到线程池,阻塞等待结果. 线程池中工作线程执行任务,发送信息,等 ...

  9. Hadoop RPC简单实例

    1.导入Hadoop-Common-2.6.0.jar导入工程,里面的IPC实现RPC需要的文件. 2.服务器端  (1)服务接口 package com.neu.rpc.server; /** * ...

随机推荐

  1. LDAP属性对照表

    AD属性对照表 姓 Sn 名 Givename 英文缩写 Initials 显示名称 displayName 描述 Description 办公室 physicalDeliveryOfficeName ...

  2. 8.3.2018 1 Quick and dirty 快而脏的快餐

    Quick and dirty  快而脏的快餐 BEIJING  北京 Food delivery is a booming business. Waste is piling up, too  送餐 ...

  3. 关于进程exit后,内存释放释放的实践

    最近碰到一个问题,或许也是小猿们都会碰到的问题:内存泄露. 都知道malloc后需要free才能释放内存,shmat后需要shmdt才能断掉内存区并使用IPC_RMID命令删除共享内存.那么如果是当前 ...

  4. php导出数组到csv格式demo

    php的二维数组导出到csv需要处理文字编码,代码如下 <?php $data=array( array("username"=>"test1",& ...

  5. Spring boot 、mybatis、swagger、c3p0、redis 和mongodb 整合

    文件路径:            添加依赖: <?xml version="1.0" encoding="UTF-8"?> <project ...

  6. Docker RestApi Create mysql Container

    docker 提供了创建容器的rest api http://192.168.150.6:8888/containers/create?name=demo-mysql docker mysql容器的参 ...

  7. 2-ubuntu下访问window的磁盘

    双系统Ubuntu无法进入Windows磁盘的解决方法 有些用户在电脑上安装了Ubuntu和Win10的双系统,正常情况下Ubuntu是可以正常访问Windows磁盘的.但是有些用户就是无法再Ubun ...

  8. Eigen库和STL容器冲突问题

    博客参考:https://blog.csdn.net/huajun998/article/details/54311561 在程序中想使用类似于如下的容器 std::vector<Eigne:: ...

  9. 部署MVC项目ManagedPipelineHandler报错

    "处理程序ExtensionlessUrlHandler-Integrated-4.0在其模块列表中有一个错误模块ManagedPipelineHandler": 解决方法:以管理 ...

  10. __slots__(面向对象进阶)

    1.__slots__是什么:是一个类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性) 2.引子:使用点来访问属性本质就是在访问类或者对象的__dic ...