使用thrift進行跨語言調用(php c# java)


1:前言

實際上本文說的是跨進程的異構語言調用,舉個簡單的例子就是利用PHP寫的代碼去調C#或是java寫的服務端。其實除了本文提供的辦法還有其他辦法,例如http+xml(json)等等都能做到。

本文的意義是介紹thrift,記錄我在調試thrift時遇到的問題和相應的解決方案,避免大家走彎路。

2:大概的流程

thrift是通過socket+序列化協議來完成跨語言調用的。類似的方案有protocolbuffer(http://code.google.com/p/protobuf/這個性能出眾,thrift性能我回頭再做測試。

使用的流程是

A:定義自己的通信接口,接口可以使用的數據類型有string,int32等,當然你也可以自己定義枚舉和結構體

B:使用thrift.exe生成相應的代碼

C:調用

3:c#,PHP,Java在調試thrift時遇到的問題

首先我們去下載thrift,地址是http://thrift.apache.org/

解壓縮后會看到

lib下就是執行的各種語言的代碼。

A:調試PHP注意事項

一定要注冊各個php代碼也就是這句。

	require_once __DIR__.'/lib/Thrift/ClassLoader/ThriftClassLoader.php';
	$loader = new ThriftClassLoader();
	$loader->registerNamespace('Thrift', __DIR__ . '/lib');
	$loader->register();

B:調試java注意事項

下載沒有提供的包

地址是:

http://commons.apache.org/proper/commons-lang/download_lang.cgi

http://hc.apache.org/downloads.cgi

http://www.slf4j.org/

3:demo

定義接口(方法名不能一樣)

View Code
enum ParameterValueType
{
  AnsiString = 1,
  Byte,
  Boolean,
  Currency = 4,
  Date,
  DateTime,
  Decimal,
  Double,
  Guid,
  Int16,
  Int32,
  Int64,
  String,
  Time,
  Xml
}

enum ParameterValueDirection 
{
   Input,
   Output,
   InputOutput,
   ReturnValue
}

enum AdoCommandType 
{
   Text,
   StoredProcedure
}

struct DBParameter {
  1: string DbParameterName,
  2: ParameterValueType DbType,
  3: string DbParameterValue,
  4: ParameterValueDirection DbDirection,
  5: i32 Size
}

struct ResultMessage {
  1: i32 IsSuccess,
  2: string ErrorMessage,
  3: string ReturnValue,
  4: list<DBParameter> ReturnParameter,
  5: list<string> DataSetColumnName,
  6: list<list<string>> DataSetRowValue
}

service DataAccessComponent {
  ResultMessage ExecuteDataset(1:string ConnectionConfigKey,2:AdoCommandType commandType,3:string commandText,4:list<DBParameter> DBParameter), 
  ResultMessage ExecuteNonQuery(1:string ConnectionConfigKey,2:AdoCommandType commandType,3:string commandText,4:list<DBParameter> DBParameter),
  ResultMessage ExecuteScalar(1:string ConnectionConfigKey,2:AdoCommandType commandType,3:string commandText,4:list<DBParameter> DBParameter),
}

生成代碼

View Code
thrift -gen java ado.thrift
thrift -gen php ado.thrift
thrift -gen csharp ado.thrift

根據語言把生成的語言放到相應的文件夾下。

下面簡單列一下調用代碼

1:PHP
	//設置IP,端口建立連接
	$socket = new TSocket('localhost', '9090');
	$transport = new TBufferedTransport($socket);
	
	//選定通信協議
	$protocol = new TBinaryProtocol($transport);
	$client = new DataAccessComponentClient($protocol); //生成的類

2:c#
server
            int port = 9090;
            DataAccess da = new DataAccess();
            // Processor
            DataAccessComponent.Processor pc = new DataAccessComponent.Processor(da);

            // Transport
            TServerSocket tServerSocket =
              new TServerSocket(port);

            // Protocol factory
            TProtocolFactory tProtocolFactory =
              new TBinaryProtocol.Factory();

            TServer serverEngine;

            // Simple Server
            serverEngine = new TSimpleServer(pc, tServerSocket);

            // ThreadPool Server
            //serverEngine = new TThreadPoolServer(pc,tServerSocket);

            // Run it
            serverEngine.Serve();

client
            TTransport transport = new TSocket("localhost", 9090);
            TProtocol protocol = new TBinaryProtocol(transport);
            ThriftTest.Client client = new ThriftTest.Client(protocol);
            transport.Open();
            int val = client.test("1213");
            client.work();
            transport.Close();
            Console.WriteLine(val);
            Console.ReadLine();
3:java
server
		try {
			//private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName());
		    
			//System.setProperty("log4j.configuration", "log4j.properties");
			
			int port = 9090;
		      // Processor
			ThriftServer testHandler =
		        new ThriftServer();
		      ThriftTest.Processor testProcessor =
		        new ThriftTest.Processor(testHandler);

		      // Transport
		      TServerSocket tServerSocket =
		        new TServerSocket(port);

		      // Protocol factory
		      TProtocolFactory tProtocolFactory =
		        new TBinaryProtocol.Factory();

		      TServer serverEngine;

		      // Simple Server
		      //serverEngine = new TSimpleServer(new Args(tServerSocket).processor(testProcessor));

		      // ThreadPool Server
		      serverEngine = new TThreadPoolServer(new TThreadPoolServer.Args(tServerSocket).processor(testProcessor).protocolFactory(tProtocolFactory));

		      //Set server event handler
		      serverEngine.setServerEventHandler(new TestServerEventHandler());

		      // Run it
		      System.out.println("Starting the server on port " + port + "...");
		      serverEngine.serve();
		      
		} catch (Exception x) {

			x.printStackTrace();

		}
		System.out.println("done.");


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM