基于 Swoole 的轻量级高性能框架 swoolefy 1.0.6 发布

栏目: 软件资讯 · 发布时间: 5年前

内容简介:swoolefy是基于swoole实现的轻量级高性能框架,框架支持http,websocket,udp服务器,以及基于tcp实现可扩展的rpc服务,同时支持composer包方式安装部署项目。基于实用,swoolefy抽象Event事件处理类,实现与底层...

swoolefy是基于swoole实现的轻量级高性能框架,框架支持http,websocket,udp服务器,以及基于tcp实现可扩展的rpc服务,同时支持composer包方式安装部署项目。基于实用,swoolefy抽象Event事件处理类,实现与底层的回调的解耦,支持同步|异步调用,内置view、log、session、 mysqlredismemcachedmongodb 等常用组件等。

swoolefy经过多个版本的迭代和实践,以及优化,性能稳定,目前已经至1.0.6版本。

1.0.6版本主要的更新:

  • 添加RpcClientManager管理器,可以方便的注册client服务实例,支持单sock连接(或者多socket连接)阻塞调用,单sock连接(或者多sock连接)并行调用,同时RpcClientManager可以在apache|php-fpm中使用。

  • RPC的服务端和RPC的客户端支持多种方式获取整包数据,包头,包体。

  • RPC配置服务化,简单配置服务即可快速搭建一个RPC的服务器和对应的RPC的服务端。

  • 组件实例化支持配置闭包回调函数。

  • 添加了进程池PoolsManager管理器,方便创建swoole_process

 github:https://github.com/bingcool/swoolefy

文档:https://www.kancloud.cn/bingcoolhuang/php-swoole-swoolefy/587501

下面是一个rpc的demo:

RPC的服务端:

1、设置协议层配置文件protocol/rpc/config.php,添加packet设置:

'packet'=>[
		// 服务端使用长度检查packet时,设置包头结构体,如果使用eof时,不需要设置,底层会读取package_eof
		'server'=>[
			'pack_header_struct' => ['length'=>'N', 'version'=>'a10', 'name'=>'a30', 'request_id'=>'a12'],
			'pack_length_key' => 'length',
			'serialize_type' => 'json'
		],
		//客户端解包设置
		'client' => [
				'pack_check_type' => 'length',
				'pack_header_struct' => ['length'=>'N', 'version'=>'a10', 'name'=>'a30', 'request_id'=>'a12'],
				'pack_length_key' => 'length',
				'serialize_type' => 'json'
		]

	],

2、服务端的控制器中

<?php
namespace Service\Coms\Book;

use Swoolefy\Core\Swfy;
use Swoolefy\Core\SController;
use Swoolefy\Core\Application;
use Swoolefy\Core\Task\TaskManager;

class BookmanageService extends SController {

	public function test($params) {
		// 客户端发送过来的数据     
		var_dump($params);
		$data = $params;
        //客户端的头部与服务端头部相同,当然可以根据返回数据不同,返回包头可以不同。
		$header = ['length'=>'', 'version'=>'1.0.1', 'name'=>'bingcool', 'request_id'=>$this->getRpcPackHeader()['request_id']];
		//   返回数据给客户端     
		$this->send($this->fd, $data, $header);
	}

至此,很很简单的服务端就ok了,其实就是设置一下packet就可以了。

RPC的客户端:

client端是基于swoole_client实现的,所以环境中必须安装swoole和swoole_serialize扩展。这个客户端其实是可以用在Apache|php-fpm的环境中,并且支持并行调用。

1、在/protocol/rpc/RpcServer.php的onWorkerStart中注册client的访问的服务,或者在start_init配置项中的类的onWorkerStart函数中注册服务,因为该类必须继承于Swoolefy\Core\StartInit的。

/**
	 * onWorkerStart
	 * @param    $server
	 * @return   
	 */
	public function onWorkerStart($server, $worker_id) {
		if(Swfy::isWorkerProcess()) {
			$productServiceConfig = [
				'servers' => '127.0.0.1:9504',
				'timeout' => 0.5,
				'noblock' => 0
			];

			$orderServiceConfig = array(
				'servers' => '127.0.0.1:9506',
				'timeout' => 0.5,
				'noblock' => 0
			);
			//客户端pack长度检查设置
			$setting = array(
				'open_length_check'     => 1,
			    'package_length_type'   => 'N',
			    'package_length_offset' => 0,       //第N个字节是包长度的值
			    'package_body_offset'   => 56,       //第几个字节开始计算长度
			    'package_max_length'    => 2000000,  //协议最大长度
			);
			// 包头结构体设置,默认客户端与服务端包头结构体相同
			$header_struct = array(
				'length'=>'N', 
				'version'=>'a10', 
				'name'=>'a30', 
				'request_id'=>'a12'
			);
			// 注册product服务
			RpcClientManager::getInstance(true)->registerService('productService', productServiceConfig, $setting, $header_struct,[
				// swoole_client 长连接             	
				'swoole_keep' => false
			]);
			// 注册order服务
			RpcClientManager::getInstance(true)->registerService('orderService', $orderServiceConfig, $setting, $header_struct,[
            // swoole_client 长连接
				'swoole_keep' => true
			]);
		}
	}

2、在controller或者model中可以直接调用向服务端发送数据
a、阻塞调用,请求/应答模式

public function test() {
		$callable = 'Service\Coms\Book\BookmanageService::test';
		$params = ['content'=>'我是rpc的客户端,我向你发送消息'];
		$header = ['length'=>'', 'version'=>'1.0.0', 'name'=>'bingcool'];
        //调用发送数据
		$client1 = RpcClientManager::getInstance()->getServices('productService')->buildHeaderRequestId($header)->waitCall($callable, $params);
        //阻塞等待数据返回
		$res1 = $client1->waitRecv();
		var_dump($res1);
}

上面将返回一个数据,数组里有两个元素,arr[0]是包头,arr[1]是包体数据,例如:

array(2) {
  [0] => array(4) {
    ["length"] => int(83)
    ["version"] => string(10) "1.0.0"
    ["name"] => string(30) "bingcool"
    ["request_id"] => string(12) "d189dfd5b997"
  }
  [1] => array(4) {
    ["content"] => array(1) {
      ["content"] => string(16) "我是rpc的服务端,我已收到你发送的消息"
  }
}

b、并行调用,然后在时间内等待接收所有数据,再进行数据聚合

// productService 调用
$callable = 'Service\Coms\Book\BookmanageService::test';
$params = ['content'=>'hhhhhhhhhhhhhhhh'];
$header = ['length'=>'', 'version'=>'1.0.1', 'name'=>'bingcool'];
$client2 = RpcClientManager::getInstance()->getServices('productService')->buildHeaderRequestId($header)->waitCall($callable, $params);

// orderService 调用
$callable = 'Service\Coms\Book\BookmanageService::test';
$params = ['content'=>'hhhhhhhhhhhhhhhh'];
$header = ['length'=>'', 'version'=>'1.0.1', 'name'=>'bingcool'];
$client3 = RpcClientManager::getInstance()->getServices('orderService')->buildHeaderRequestId($header)->waitCall($callable, $params);

// productService 调用
$callable = 'Service\Coms\Book\BookmanageService::test';
$params = ['content'=>'hhhhhhhhhhhhhhhh'];
$header = ['length'=>'', 'version'=>'1.0.1', 'name'=>'bingcool'];
$client4 = RpcClientManager::getInstance()->getServices('productService')->buildHeaderRequestId($header)->waitCall($callable, $params);

// productService 调用
$callable = 'Service\Coms\Book\BookmanageService::test';
$params = ['content'=>'hhhhhhhhhhhhhhhh'];
$header = ['length'=>'', 'version'=>'1.0.1', 'name'=>'bingcool'];
$client5 = RpcClientManager::getInstance()->getServices('productService')->buildHeaderRequestId($header)->waitCall($callable, $params);
// 并行等待数据返回,这里返回的是所有调用的数据,例如上面调用4次,那么将返回给数组$res中4个整包元素
$res = RpcClientManager::getInstance()->multiRecv();
var_dump($res);
~~~
那么如何获取其中某一个的客户端的数据呢,很简单
~~~
// 获取整包数据,包括包头和包体
$pack_data = $client2->getResponsePackData();
// 分离包头包体
list($pack_header, $pack_body) = $pack_data;

// 直接获取包头
$pack_header = $client2->getResponsePackHeader();
或者
$pack_header = $pack_data[0];

// 直接获取包头
$pack_body = $client2->getResponsePackBody();
或者
$pack_body =  $pack_data[1];

这是一个简单的说明,具体可以参考文档。


【声明】文章转载自:开源中国社区 [http://www.oschina.net]


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Code

Code

Charles Petzold / Microsoft Press / 2000-10-21 / USD 29.99

Paperback Edition What do flashlights, the British invasion, black cats, and seesaws have to do with computers? In CODE, they show us the ingenious ways we manipulate language and invent new means of ......一起来看看 《Code》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试