热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

封装Thrift相关操作的PHP类

最近研究Thrift了一段时间,对Thrift的server端和client端操作的代码进行了稍微封装,这样编写一个后台服务器的时候,就专心写业务逻辑就行了,对thrift内部服务器代码不用关心,因为这些代码都是通用的。如果你不知道thrift是什么东东,我之前有写一个简单

最近研究Thrift了一段时间,对Thrift的server端和client端操作的代码进行了稍微封装,这样编写一个后台服务器的时候,就专心写业务逻辑就行了,对thrift内部服务器代码不用关心,因为这些代码都是通用的。

如果你不知道thrift是什么东东,我之前有写一个简单示例:thrift入门hello示例

我同时写了几个语言版本的服务器,有php、python和java,并作了相应测试。client端用的php。

作为测试,我以thrift的IDL格式写了一个简单的服务接口 mongotest.thrift:

namespace php mongotest
namespace py mongotest
service MongoTest {
    string getServerStatus();
}

这个服务功能就是查看mongodb数据库的连接状态,这样就可以测试这种开发方式连接数据库的一些行为。

下面帖出封装的server类,并写出生成一个服务端实例的代码。

java版server,ThriftServer.java

import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TServer.Args;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.server.TThreadedSelectorServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TSSLTransportFactory;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TServerTransport;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerTransport;
import org.apache.thrift.transport.TTransportFactory;
import org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.protocol.TCompactProtocol;
public class ThriftServer {
  public org.apache.thrift.TProcessor processor;
  public ThriftServer(org.apache.thrift.TProcessor processor){
    this.processor = processor;
  }
  public void startServer() {
    try {
        //这里可以选择TThreadPoolServer 和 TThreadedSelectorServer
      Runnable threadPool = new Runnable() {
        public void run() {
          threadPool(processor);
        }
      };
      //Runnable secure = new Runnable() {
        //public void run() {
          //secure(processor);
        //}
      //};
      new Thread(threadPool).start();
      //new Thread(secure).start();
    } catch (Exception x) {
      x.printStackTrace();
    }
  }
  public void threadPool(org.apache.thrift.TProcessor processor) {
    try {
      TServerTransport serverTransport = new TServerSocket(9090);
      //TServer server = new TSimpleServer(new Args(serverTransport).processor(processor));
      // Use this for a multithreaded server
      TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverTransport).processor(processor);
      args.maxWorkerThreads = 50;
      TServer server = new TThreadPoolServer(args);
      System.out.println("Starting the server...");
      server.serve();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  public void threadSelector(org.apache.thrift.TProcessor processor) {
    try {
      TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(9090);
      //异步IO,需要使用TFramedTransport,它将分块缓存读取。
      TTransportFactory transportFactory = new TFramedTransport.Factory();
      //使用高密度二进制协议
      TProtocolFactory proFactory = new TCompactProtocol.Factory();
      TServer server = new TThreadedSelectorServer(
              new TThreadedSelectorServer.Args(serverTransport)
              .protocolFactory(proFactory)
              .transportFactory(transportFactory)
              .processor(processor)
              );
      System.out.println("Starting the server...");
      server.serve();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  public void secure(org.apache.thrift.TProcessor processor) {
    try {
      /*
       * Use TSSLTransportParameters to setup the required SSL parameters. In this example
       * we are setting the keystore and the keystore password. Other things like algorithms,
       * cipher suites, client auth etc can be set.
       */
      TSSLTransportParameters params = new TSSLTransportParameters();
      // The Keystore contains the private key
      params.setKeyStore("./lib/java/test/.keystore", "thrift", null, null);
      /*
       * Use any of the TSSLTransportFactory to get a server transport with the appropriate
       * SSL configuration. You can use the default settings if properties are set in the command line.
       * Ex: -Djavax.net.ssl.keyStore=.keystore and -Djavax.net.ssl.keyStorePassword=thrift
       *
       * Note: You need not explicitly call open(). The underlying server socket is bound on return
       * from the factory class.
       */
      TServerTransport serverTransport = TSSLTransportFactory.getServerSocket(9093, 0, null, params);
      //TServer server = new TSimpleServer(new Args(serverTransport).processor(processor));
      // Use this for a multi threaded server
      TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverTransport).processor(processor);
      args.maxWorkerThreads = 50;
       TServer server = new TThreadPoolServer(args);
      System.out.println("Starting the secure server...");
      server.serve();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

有了上面封装的类后,要写一个基于thrift相应服务的socket后台,就相当简单了,下面是服务器调用的例子 JavaServer.java:

import mongotest.*;
public class JavaServer {
    public static void main(String[] args){
        MongoTestHandler handler = new MongoTestHandler();  //之前定义的接口mongotest.thrift,具体实现类
        MongoTest.Processor processor = new MongoTest.Processor(handler); //这个调用的是通过thrift自动生成的类
        ThriftServer server = new ThriftServer(processor);
        server.startServer();  //这里也可以把服务器的一些参数,如端口等封装进去
    }
}

python版server,ThriftServer.py:

#!/usr/bin/env python
#encoding=utf-8
import sys
sys.path.append('./gen-py')
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
class ThriftServer:
    def __init__(self, processor, port=9090):
        self.processor = processor
        self.port = port
    def startServer(self):
        processor = self.processor
        transport = TSocket.TServerSocket(port=self.port)
        tfactory = TTransport.TBufferedTransportFactory()
        pfactory = TBinaryProtocol.TBinaryProtocolFactory()
        #server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
        # You could do one of these for a multithreaded server
        #server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
        server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
        server.daemon = True #enable ctrl+c to exit the server
        server.setNumThreads(100);
        #server = TServer.TForkingServer(processor, transport, tfactory, pfactory)
        print 'Starting the server...'
        server.serve()
        print 'done.'

python版调用示例:

#!/usr/bin/env python
#encoding=utf-8
import sys
sys.path.append('./gen-py')
from ThriftServer import ThriftServer
from MongoTestHandler import MongoTestHandler
from mongotest import MongoTest
handler = MongoTestHandler()
processor = MongoTest.Processor(handler)
server = ThriftServer(processor, 9090)
server.startServer()

php版server,ThriftServer.php:

error_reporting(E_ALL);
require_once __DIR__.'/lib/Thrift/ClassLoader/ThriftClassLoader.php';
use Thrift\ClassLoader\ThriftClassLoader;
$GEN_DIR = realpath(dirname(__FILE__).'').'/gen-php';
$loader = new ThriftClassLoader();
$loader->registerNamespace('Thrift', __DIR__ . '/lib');
$loader->register();
use Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\TPhpStream;
use Thrift\Transport\TBufferedTransport;
use Thrift\Server\TServerSocket;
use Thrift\Server\TForkingServer;
use Thrift\Factory\TTransportFactory;
use Thrift\Factory\TBinaryProtocolFactory;
class ThriftServer {
    private $processor;
    private $server_ip;
    private $server_port;
    function __construct($processor, $server_ip="localhost", $server_port=9090){
        $this->processor = $processor;
        $this->server_ip = $server_ip;
        $this->server_port = $server_port;
    }
    function startServer(){
        $processor = $this->processor;
        try {
            $transport = new TServerSocket($this->server_ip, $this->server_port);
        } catch (Exception $e) {
            echo 'port already in use.';
            exit();
        }
        $outputTransportFactory = $inputTransportFactory = new TTransportFactory($transport);
        $outputProtocolFactory = $inputProtocolFactory = new TBinaryProtocolFactory();
        $server = new TForkingServer(
            $processor,
            $transport,
            $inputTransportFactory,
            $outputTransportFactory,
            $inputProtocolFactory,
            $outputProtocolFactory
        );
        header('Content-Type: application/x-thrift');
        print 'Starting the server...';
        $server->serve();
    }
}

php调用示例,PhpServer.php:

include_once __DIR__.'/gen-php/mongotest/MongoTest.php';
include_once __DIR__.'/MongoTestHandler.php';
include_once __DIR__.'/ThriftServer.php';
error_reporting(E_ALL);
$handler = new MongoTestHandler();
$processor = new \mongotest\MongoTestProcessor($handler);
$server = new ThriftServer($processor);
$server->startServer();

对于客户端,只做了php一个版本,其它语言也很容易,下面是php版client封装类,ThriftClient.php:

error_reporting(E_ALL);
require_once __DIR__.'/lib/Thrift/ClassLoader/ThriftClassLoader.php';
use Thrift\ClassLoader\ThriftClassLoader;
$GEN_DIR = realpath(dirname(__FILE__)).'/gen-php';
$loader = new ThriftClassLoader();
$loader->registerNamespace('Thrift', __DIR__ . '/lib');
$loader->register();
use Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\TSocket;
use Thrift\Transport\THttpClient;
use Thrift\Transport\TBufferedTransport;
use Thrift\Exception\TException;
class ThriftClient {
    public $client;
    private $transport;
    private $protocol;
    private $client_class;
    private $server_ip;
    private $server_port;
    private $socket;
    function __construct($client_class, $server_ip='localhost', $server_port=9090){
        $this->client_class = $client_class;
        $this->server_ip = $server_ip;
        $this->server_port = $server_port;
    }
    function __destruct(){
        $this->transport->close();
    }
    public function getClient(){
        $this->socket = new TSocket($this->server_ip, $this->server_port);
        $this->transport = new TBufferedTransport($this->socket, 1024, 1024);
        $this->protocol = new TBinaryProtocol($this->transport);
        $this->client = new \mongotest\MongoTestClient($this->protocol);
        $this->transport->open();
        return $this->client;
    }
}
?>

php版client调用示例,MongoTest-client-thrift.php:

include_once __DIR__.'/gen-php/mongotest/MongoTest.php';
include_once __DIR__.'/ThriftClient.php';
$thrift = new ThriftClient('\mongotest\MongoTestClient', 'localhost', 9090);
$client = $thrift->getClient();
$ret = $client->getServerStatus();   //调用服务方法
echo $ret;
?>

相关代码打包(省略了thrift的库和通过thrift命令自动生成的代码,及一些jar依赖包,如mongodb包)


推荐阅读
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • Allegro总结:1.防焊层(SolderMask):又称绿油层,PCB非布线层,用于制成丝网印板,将不需要焊接的地方涂上防焊剂.在防焊层上预留的焊盘大小要比实际的焊盘大一些,其差值一般 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • 目录浏览漏洞与目录遍历漏洞的危害及修复方法
    本文讨论了目录浏览漏洞与目录遍历漏洞的危害,包括网站结构暴露、隐秘文件访问等。同时介绍了检测方法,如使用漏洞扫描器和搜索关键词。最后提供了针对常见中间件的修复方式,包括关闭目录浏览功能。对于保护网站安全具有一定的参考价值。 ... [详细]
  • PHP组合工具以及开发所需的工具
    本文介绍了PHP开发中常用的组合工具和开发所需的工具。对于数据分析软件,包括Excel、hihidata、SPSS、SAS、MARLAB、Eview以及各种BI与报表工具等。同时还介绍了PHP开发所需的PHP MySQL Apache集成环境,包括推荐的AppServ等版本。 ... [详细]
  • Tomcat安装与配置教程及常见问题解决方法
    本文介绍了Tomcat的安装与配置教程,包括jdk版本的选择、域名解析、war文件的部署和访问、常见问题的解决方法等。其中涉及到的问题包括403问题、数据库连接问题、1130错误、2003错误、Java Runtime版本不兼容问题以及502错误等。最后还提到了项目的前后端连接代码的配置。通过本文的指导,读者可以顺利完成Tomcat的安装与配置,并解决常见的问题。 ... [详细]
  • .htaccess文件 ... [详细]
author-avatar
Maze-HYW_276
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有