posts - 156,  comments - 601,  trackbacks - 0

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定义发布)

<bean class="com.baidu.jprotobuf.rpc.server.IDLServiceExporter">
        <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注解类发布)
 <bean class="com.baidu.jprotobuf.rpc.server.AnnotationServiceExporter">
        <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接口
public interface 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;
}

public class SimpleIDLInvoker implements ServerInvoker {

    @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 文件定义:

package pkg;  

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>
        <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进行访问,示例代码如下:

    @Test
    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进行访问,示例代码如下:

    @Test
    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对象代码:

public class 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进行访问

    <bean id="simpleTestClientForIDLProxy" class="com.baidu.jprotobuf.rpc.client.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进行访问

    <bean id="simpleTestClientForAnnotationProxy" class="com.baidu.jprotobuf.rpc.client.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

package pkg;  

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;
}  

下面示例只演示了客户端的配置,服务发布的配置也是相同

    <bean id="simpleTestClientForIDLProxy" class="com.baidu.jprotobuf.rpc.client.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>


联系我们

email: rigel-opensource@baidu.com


posted on 2014-10-10 15:20 x.matthew 阅读(3482) 评论(0)  编辑  收藏 所属分类: 最新开源动态Spring|Hibernate|Other framework其它

只有注册用户登录后才能发表评论。


网站导航: