jprotobuf-rpc-http 是应用jprotobuf类库实现基于http协议的RPC开发组件。 目前1.0提供可以直接把Google protobuf的IDL定义语言发布成RPC服务,客户端也可以直接应用IDL定义语言进行动态创建,帮助开发完全省去了手工编译protobuf IDL语言的麻烦。
jprotobuf-rpc-http文档: https://github.com/jhunters/JProtobuf-rpc-http
jprotobuf文档:https://github.com/jhunters/jprotobuf
环境要求
JDK 6 或以上版本 Spring 3.0+
API使用说明
RPC服务的发布
a1 在Spring配置文件,定义IDLServiceExporter服务发布配置 (直接由IDL定义发布)
< property name ="serviceName" value ="SimpleIDLTest" ></ property >
< property name ="invoker" ref ="simpleIDLInvoker" ></ property >
< property name ="inputIDL" value ="classpath:/simplestring.proto" ></ property >
< property name ="outputIDL" value ="classpath:/simplestring.proto" ></ property >
</ bean >
< bean id ="simpleIDLInvoker" class ="com.baidu.bjf.SimpleIDLInvoker" ></ bean >
inputIDL 属性表示接收的protobuf协议定义 outputIDL 属性表示返回的protobuf协议定义 serviceName 服务名称,必须填写。 在服务的servlet发布后,服务名称会以path路径方式查找 invoker 服务回调实现,必须实现 com.baidu.jprotobuf.rpc.server.ServerInvoker接口
a2 在Spring配置文件,定义AnnotationServiceExporter服务发布配置 (通过Jprotobuf注解类发布)
< property name ="serviceName" value ="SimpleIDLTest2" ></ property >
< property name ="invoker" ref ="simpleIDLInvoker" ></ property >
< property name ="inputClass" value ="com.baidu.bjf.StringMessagePOJO" ></ property >
< property name ="outputClass" value ="com.baidu.bjf.StringMessagePOJO" ></ property >
</ bean >
< bean id ="simpleIDLInvoker" class ="com.baidu.bjf.SimpleIDLInvoker" ></ bean >
inputClass 属性表示接收的JProtobuf注解POJO类 outputClass 属性表示返回的JProtobuf注解POJO类 serviceName 服务名称,必须填写。 在服务的servlet发布后,服务名称会以path路径方式查找 invoker 服务回调实现,必须实现 com.baidu.jprotobuf.rpc.server.ServerInvoker接口
/**
* RPC service call back method.
*
* @param input request IDL proxy object by protobuf deserialized
* @param output return back IDL proxy object to serialized
* @throws Exception in case of any exception
*/
void invoke(IDLProxyObject input, IDLProxyObject output) throws Exception;
}
@Override
public void invoke(IDLProxyObject input, IDLProxyObject output) throws Exception {
if (input != null) {
System.out.println(input.get("list"));
}
if (output != null) {
output.put("list", "hello world");
}
}
}
simplestring.proto 文件定义:
option java_package = "com.baidu.bjf.remoting.protobuf.simplestring" ;
option java_outer_classname = "StringTypeClass" ;
message StringMessage {
required string list = 1 ;
}
b web.xml文件配置服务发布servlet
< servlet-name >protobufExporter </ servlet-name >
< servlet-class >com.baidu.jprotobuf.rpc.server.HttpRequestHandlerServlet </ servlet-class >
</ servlet >
< servlet-mapping >
< servlet-name >protobufExporter </ servlet-name >
< url-pattern >/remoting/* </ url-pattern >
</ servlet-mapping >
RPC客户端的API开发
RPC客户端使用IDLProxyFactoryBean进行访问,示例代码如下:
public void testProxyFactoryBean() throws Exception {
String idl = "package pkg; " +
"option java_package = \"com.baidu.bjf.remoting.protobuf.simplestring\";" +
"option java_outer_classname = \"StringTypeClass\";" +
"message StringMessage { required string list = 1;} ";
ByteArrayResource resource = new ByteArrayResource(idl.getBytes());
IDLProxyFactoryBean proxyFactoryBean = new IDLProxyFactoryBean();
proxyFactoryBean.setServiceUrl("http://localhost:8080/myfirstproject/remoting/SimpleIDLTest");
proxyFactoryBean.setInputIDL(resource);
proxyFactoryBean.setOutputIDL(resource);
proxyFactoryBean.afterPropertiesSet();
ClientInvoker invoker = proxyFactoryBean.getObject();
// set request param
IDLProxyObject input = invoker.getInput();
input.put("list", "how are you!");
IDLProxyObject output = invoker.invoke(input);
System.out.println(output.get("list"));
}
RPC客户端使用AnnotationProxyFactoryBean进行访问,示例代码如下:
public void testClientProxy() throws Exception {
AnnotationProxyFactoryBean<StringMessagePOJO, StringMessagePOJO> factoryBean;
factoryBean = new AnnotationProxyFactoryBean<StringMessagePOJO, StringMessagePOJO>();
factoryBean.setServiceUrl("http://localhost:8080/myfirstproject/remoting/SimpleIDLTest");
factoryBean.setInputClass(StringMessagePOJO. class);
factoryBean.setOutputClass(StringMessagePOJO. class);
factoryBean.afterPropertiesSet();
ClientInvoker<StringMessagePOJO, StringMessagePOJO> invoker = factoryBean.getObject();
StringMessagePOJO input = invoker.getInput();
if (input != null) {
input.setList("how are you!");
}
StringMessagePOJO output = invoker.invoke(input);
if (output != null) {
System.out.println(output.getList());
}
}
StringMessagePOJO对象代码:
@Protobuf(fieldType = FieldType.STRING, order = 1, required = true)
private String list;
/**
* get the list
* @return the list
*/
public String getList() {
return list;
}
/**
* set list value to list
* @param list the list to set
*/
public void setList(String list) {
this.list = list;
}
}
RPC客户端Spring配置
RPC客户端使用IDLProxyFactoryBean进行访问
< property name ="inputIDL" value ="classpath:/simplestring.proto" ></ property >
< property name ="outputIDL" value ="classpath:/simplestring.proto" ></ property >
< property name ="inputIDLObjectName" value ="StringMessage" ></ property >
< property name ="serviceUrl" value ="http://localhost:8080/myfirstproject/remoting/SimpleIDLTest" ></ property >
</ bean >
RPC客户端使用AnnotationProxyFactoryBean进行访问
< property name ="inputClass" value ="com.baidu.bjf.remoting.protobuf.FieldType.StringMessagePOJO" ></ property >
< property name ="outputClass" value ="com.baidu.bjf.remoting.protobuf.FieldType.StringMessagePOJO" ></ property >
< property name ="serviceUrl" value ="http://localhost:8080/myfirstproject/remoting/SimpleIDLTest" ></ property >
</ bean >
多个IDL message定义解决方案
例如下面定义了多个message定义时,则在服务发布以及客户连接时,需要指定objectName
option java_package = "com.baidu.bjf.remoting.protobuf.simplestring" ;
option java_outer_classname = "StringTypeClass" ;
message StringMessage {
required string list = 1 ;
optional StringMessage2 msg = 2 ;
}
message StringMessage2 {
required string name = 1 ;
}
下面示例只演示了客户端的配置,服务发布的配置也是相同
< property name ="inputIDL" value ="classpath:/simplestring.proto" ></ property >
< property name ="outputIDL" value ="classpath:/simplestring.proto" ></ property >
< property name ="inputIDLObjectName" value ="StringMessage" ></ property >
< property name ="serviceUrl" value ="http://localhost:8080/myfirstproject/remoting/SimpleIDLTest" ></ property >
</ bean >
联系我们
email: rigel-opensource@baidu.com