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. 阿里云 Aliplayer高级功能介绍(六):进度条标记

    基本介绍 Aliplayer在进度条上提示时间和缩略图功能外,还可以进行视频内容的提示打点,当然不止是进度条上显示打点的内容,还提供一组接口,方便用户进行打点时间和内容的获取, 基本UI如下图所示: ...

  2. SQL Server中存储过程与函数的区别

    本质上没区别.只是函数有如:只能返回一个变量的限制.而存储过程可以返回多个.而函数是可以嵌入在sql中使用的,可以在select中调用,而存储过程不行.执行的本质都一样. 函数限制比较多,比如不能用临 ...

  3. 稀疏表示step by step(转)

    原文地址:稀疏表示step by step(转)作者:野火春风 稀疏表示step by step(1)     声明:本人属于绝对的新手,刚刚接触“稀疏表示”这个领域.之所以写下以下的若干个连载,是鼓 ...

  4. python生成VOC2007的类库

    VOCAnnotation.py: # -*-coding:utf-8-*- from lxml import etree import os class VOCAnnotation(object): ...

  5. Gradle:gradle下载插件

    https://github.com/michel-kraemer/gradle-download-task 用法在readme中已经讲的很清楚了,我主要介绍下注意事项吧. 我用这个插件的目的是为了让 ...

  6. 用户测评 | EDAS Serverless 上手体验

    背景 最初, 是因为对 Serverless 这一概念感兴趣, 所以开始试用阿里云函数计算,使用过程中感受到了函数计算快速.按需付费和弹性伸缩等方面的优势,随后我在天气预报.发送短信等场景下开始了更深 ...

  7. win10系统下安装打印机驱动

    以前安装过一次打印机的驱动,当时是从网上下载的,今天按照以前的方法安装打印机驱动,发现并不能使用,而且并不知道驱动还能自动安装. 首先在系统图标下选择设置-设备和打印机-添加打印机-搜索打印机,如果没 ...

  8. GitBook的使用方法

    ---恢复内容开始--- 由于近期工作中使用gitbook编写讲义,现把出现的问题总结下: 1 . gitbook的安装 Gitbook与word等办公软件类似,能够编写文档,Gitbook中编写文档 ...

  9. js 实现继承

    我们现在要做的一件事情是像其他语言的面向对象一下实现继承多态 具体要求如下: 一个 Father 构造函数,一个 Child 构造函数,其中改写 Father中的部分参数, new Child() 表 ...

  10. Markdown图片