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.thriftthrift -gen php ado.thriftthrift -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:javaservertry {//private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName()); //System.setProperty("log4j.configuration", "log4j.properties");int port = 9090; // ProcessorThriftServer 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.");