thrift的使用中一般是一个Server对应一个Processor和一个Transport,如果有多个服务的话,那必须要启动多个Server,占用多个端口,这种方式显然不是我们想要的,所以thrift为我们提供了复用端口的方式,通过监听一个端口就可以提供多种服务,这种方式需要用到两个类:TMultiplexedProcessor和TMultiplexedProtocol。

创建 2 个 Laravel 项目,thrift-server (服务端) 和 thrift-client (客户端)

 
文件目录
testServer.thrift:

namespace php Rpc.Test

enum Operation {
ADD = ,
SUBTRACT = ,
MULTIPLY = ,
DIVIDE =
} exception InvalidOperation {
: i32 whatOp,
: string why
} service Calculator {
double calculate(:double num1, :double num2, :Operation op) throws (:InvalidOperation ouch),
string echoString(: string str) ,
} service Echo {
string echo(: string str) ,
}

每个service类对应一种服务,服务类下可有多个方法。

thrift-server根目录生成客户端类命令:

thrift -r --out ./ --gen php thriftSource/testServer.thrift

将生成的Rpc/Test文件夹剪切到thrift-client项目的Rpc目录中

在thrift-server根目录继续生成服务端类:

thrift -r --out ./ --gen php:server thriftSource/testServer.thrift

根目录创建Service目录,存放实现Calculator和Echo类的文件
Service/CalculatorService.php

<?php
/**
* 实现Calculator服务
*/ namespace Service; use Rpc\Test\CalculatorIf;
use Rpc\Test\Operation;
use Rpc\Test\InvalidOperation; class CalculatorService implements CalculatorIf {
/**
* @param double $num1
* @param double $num2
* @param int $op
* @return double
* @throws InvalidOperation
*/
public function calculate($num1, $num2, $op) {
switch ($op) {
case Operation::ADD:
$val = $num1 + $num2;
break;
case Operation::SUBTRACT:
$val = $num1 - $num2;
break;
case Operation::MULTIPLY:
$val = $num1 * $num2;
break;
case Operation::DIVIDE:
if ($num2 == ) {
$io = new InvalidOperation();
$io->whatOp = $op;
$io->why = "Cannot divide by 0";
throw $io;
}
$val = $num1 / $num2;
break;
default:
$io = new InvalidOperation();
$io->whatOp = $op;
$io->why = "Invalid Operation";
throw $io;
}
return $val;
} /**
* @param $string
*/
public function echoString($string) {
return $string;
}
}

Service/EchoService.php:

<?php
/**
* 实现Echo服务
*/ namespace Service; use Rpc\Test\EchoIf; class EchoService implements EchoIf { /**
* @param $string
*/
public function echo($string) {
return $string;
}
}
thrift-server服务端控制器: <?php
/**
* 服务端控制器
*/ namespace App\Http\Controllers; use Rpc\Test\CalculatorProcessor;
use Rpc\Test\EchoProcessor;
use Service\CalculatorService;
use Service\EchoService;
use Illuminate\Http\Request;
use Thrift\Protocol\TBinaryProtocol;
use Thrift\TMultiplexedProcessor;
use Thrift\Transport\TBufferedTransport;
use Thrift\Transport\TPhpStream;
use Thrift\Exception\TException; class ServerController extends Controller
{
/**
* 多个服务
* @param Request $request
*/
function handleManyRequest(Request $request) {
try{
header('Content-Type', 'application/x-thrift'); // 初始化多个服务提供者handle
$calculatorhandler = new CalculatorService();
$echohandler = new EchoService(); $multiplexedProcessor = new TMultiplexedProcessor(); // 创建多个服务Processor
$calculatorProcessor = new CalculatorProcessor($calculatorhandler);
$echoProcessor = new EchoProcessor($echohandler); // 将服务注册到TMultiplexedProcessor中
$multiplexedProcessor->registerProcessor("calculator", $calculatorProcessor);
$multiplexedProcessor->registerProcessor("echo", $echoProcessor); // 初始化数据传输方式transport
$transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));
// 利用该传输方式初始化数据传输格式protocol
$protocol = new TBinaryProtocol($transport, true, true); // 开始服务
$transport->open();
$multiplexedProcessor->process($protocol, $protocol);
$transport->close();
} catch (TException $tx) {
print 'TException: '.$tx->getMessage()."\n";
}
}
}

配置post方式路由

Route::post('/rpc/server', 'ServerController@handleManyRequest');

配置虚拟主机 8081 端口监听thrift-server服务,80端口监听thrift-client服务

thrift-client客户端控制器:

<?php
/**
* 客户端控制器
*/ namespace App\Http\Controllers; use Rpc\Test\Operation;
use Rpc\Test\CalculatorClient;
use Rpc\Test\EchoClient;
use Illuminate\Http\Request;
use Thrift\Protocol\TBinaryProtocol;
use Thrift\Protocol\TMultiplexedProtocol;
use Thrift\Transport\THttpClient;
use Thrift\Transport\TBufferedTransport;
use Thrift\Exception\TException; class ClientController extends Controller
{
/**
* 多服务
* @param Request $request
*/
function handleManyRequest(Request $request) {
try{
// 定义连接
$socket = new THttpClient('127.0.0.1', , '/rpc/server'); // 创建transport
$transport = new TBufferedTransport($socket, , );
// 基于Transport创建Protocol
$protocol = new TBinaryProtocol($transport); // 创建Client调用服务接口的方法
$calculatorClient = new CalculatorClient(new TMultiplexedProtocol($protocol, "calculator"));
$echoClient = new EchoClient(new TMultiplexedProtocol($protocol, "echo")); // 开启
$transport->open(); // 调用接口方法
$sum = $calculatorClient->calculate(, , Operation::ADD);
print "calculator service -> calculate function -> 1+2=$sum </br>"; $test = $calculatorClient->echoString('this it test');
print "calculator service -> echoString function -> echoString:$test </br>"; $echoString = $echoClient->echo('echo method');
print "echo service -> echo function -> echo:$echoString\n\r"; $transport->close(); } catch (TException $tx) {
print 'TException: '.$tx->getMessage()."\n";
}
}
}

由此可客户端可调用服务端的方法,实现通讯:

 
postman测试thrift

注意:
1、根目录新建目录需配置composer.json中的psr-4
2、取消http/kernel.php中web中间件内容

转载:https://www.jianshu.com/p/99405b3072b1

php Laravel Thrift使用TMultiplexedProcessor复用端口模式的更多相关文章

  1. Thrift 的五种工作模式

    一.thrift 共有5中工作模式,分成阻塞和非阻塞: 阻塞:TSimpleServer.TThreadPoolServer 非阻塞:TNonblockingServer.THsHaServer.TT ...

  2. 端口复用技术简单了解;重用端口;socket复用端口

    端口复用相关点 多个应用复用端口,只有最后一个绑定的socket可以接受数据,所有socket都可以发送数据 使用端口复用技术时,所有的socket都开启端口复用,才可以实现端口复用 黑客技术,使用标 ...

  3. Access、Trunk和Hybrid三种端口模式

    网络交换机(英语:Network switch)是一个扩大网络的器材,能为子网中提供更多的连接端口,以便连接更多的电脑. 通俗来说其起到的作用就是把一个网络端口分成多个网络端口 交换机和路由器的区别 ...

  4. 交换机三种端口模式Access、Hybrid和Trunk

    以太网端口有 3种链路类型:access.trunk.hybird 什么是链路类型? vlan的链路类型可以分为接入链路和干道链路. 1.接入链路(access link)指的交换机到用户设备的链路, ...

  5. Thrift笔记(六)--单端口 多服务

    多个服务,使用监听一个端口.先上一个demo Test.thrift namespace java com.gxf.thrift enum RequestType { SAY_HELLO, //问好 ...

  6. PHP laravel+thrift+swoole打造微服务框架

    Laravel作为最受欢迎的php web框架一直广受广大互联网公司的喜爱. 笔者也参与过一些由laravel开发的项目.虽然laravel的性能广受诟病但是业界也有一些比较好的解决方案,比如堆机器, ...

  7. vlan与交换机端口模式Access,Hybrid,Trunk

    以太网端口有三种链路类型:Access.Hybrid和Trunk.Access类型的端口只能属于1个VLAN,一般用于连接计算机的端口:Trunk类型的端口可以允许多个VLAN通过,可以接收和发送多个 ...

  8. 【iCore4 双核心板_FPGA】例程十:FSMC总线通信实验——复用地址模式

    实验原理: STM32F767上自带FMC控制器,本实验将通过FMC总线的地址复用模式实现STM32与FPGA 之间通信,FPGA内部建立RAM块,FPGA桥接STM32和RAM块,本实验通过FSMC ...

  9. 【iCore1S 双核心板_FPGA】例程十三:FSMC总线通信实验——复用地址模式

    实验原理: STM32F103上自带FMC控制器,本实验将通过FMC总线的地址复用模式实现STM32与FPGA 之间通信,FPGA内部建立RAM块,FPGA桥接STM32和RAM块,本实验通过FSMC ...

随机推荐

  1. Tensorflow技巧

    1.尽量控制图片大小在1024以内,不然显存会爆炸. 2.尽量使用多GPU并行工作,训练下降速度快. 3.当需要被检测的单张图片里物体太多时,记得修改Region_proposals的个数 4.测试的 ...

  2. 2019-1-29-Roslyn-使用-WriteLinesToFile-解决参数过长无法传入

    title author date CreateTime categories Roslyn 使用 WriteLinesToFile 解决参数过长无法传入 lindexi 2019-01-29 16: ...

  3. 如何将本地项目上传到Git 版本库

    1.(先进入项目文件夹)通过命令 git init 把这个目录变成git可以管理的仓库 git init 2.把文件添加到版本库中,使用命令 git add .添加到暂存区里面去,不要忘记后面的小数点 ...

  4. Linux程序包管理初步-rpm的使用

    在Linux系统上,一般而言,对于程序包管理器来说分为三类: debian:dpt,dpkg;             (程序包后缀.deb) rhel:rpm (程序包后缀.rpm) suse:rp ...

  5. golang中函数类型

    今天看Martini文档,其功能列表提到完全兼容http.HandlerFunc接口,就去查阅了Go: net/http的文档,看到type HandlerFunc这部分,顿时蒙圈了.由于之前学习的时 ...

  6. 时序数据库连载系列: 时序数据库一哥InfluxDB之存储机制解析

    InfluxDB 的存储机制解析 本文介绍了InfluxDB对于时序数据的存储/索引的设计.由于InfluxDB的集群版已在0.12版就不再开源,因此如无特殊说明,本文的介绍对象都是指 InfluxD ...

  7. Django项目:CRM(客户关系管理系统)--32--24PerfectCRM实现King_admin自定义操作数据

    #admin.py # ————————01PerfectCRM基本配置ADMIN———————— from django.contrib import admin # Register your m ...

  8. PHP搜索优化 sphinx 搭建测试

    安装.环境:win7 64位 1.下载sphinx文件包 下载地址:http://sphinxsearch.com/downloads/archive/ 2.解压到D:/sphinx.新建文件夹dat ...

  9. iview中table的render()函数

    Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更接 ...

  10. 在vscode中使用字体Cascadia Code

    下载字体 下载地址:github:https://github.com/microsoft/cascadia-code/releases 安装字体(windows10) 设置 > 个性化 > ...