|
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."); |
|