Grails中实现远程rpc
> Grails中会不可避免的遇到跨平台/域远程调用,远程rpc是最方便的选择
>
> Grails的Remoting 插件 http://grails.org/plugin/remoting 是最好的选择了,它支持 RMI、Hessian, Burlap, HttpInvoker, XFire协议。
安装
---
grails install-plugin remoting
服务端实现
---
我们打算用hessian协议做示例。
1. 定义rpc接口
在 Grails 工程的 `src/java` 目录下写好rpc接口,如,我们定一个接口
java:
public interface ISynchronizeService {
/**
* 获得分类
* @param 客户端版本
* @return
*/
Series getSeries(long client_version);
/**
* 获得元素
* @param 客户端版本
* @return
*/
Item getItems(long client_version);
}
这个接口提供了两个方法,分别获取不同的数据。
然后再在 `src/java` 目录下建好所涉及的POJO类。
Series.java
java:
/**
* POJO 分类
*/
public class Series implements Serializable {
private static final long serialVersionUID = -1666133446403499930L;
/**
* 分类名称
*/
private String name;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
public Series() { }
}
Item.java 略过,同Series.java
这些需要远程传输的POJO必须可以序列化,所以所涉及到的POJO必须实现Serializable接口。
2. 实现rpc services
新建一个Grails services,名字可以随便取,但必须实现上面定义的接口:
java:
class SynchronizeService implements ISynchronizeService {
//暴露为hessian协议的webservice
static expose = ['hessian']
/**
* 同步分类
* @param 客户端版本
* @return
*/
@Override
public Series getSeries(long client_version) {
//从数据库查询
def sSeries = StoreSeries.findById(1)
//组装pojo
def series = new Series()
series.setName(sSeries.name)
return series;
}
/**
* 同步元素
* @param 客户端版本
* @return
*/
@Override
public Item getItems(long client_version) {
//从数据库查询
def sItem = StoreItem.findById(1)
//组装pojo
def item = new Item()
item.setName(sItem.name)
return item;
}
}
静态属性expose用来指定service所暴露的rpc协议,这里我们指定为hessian,当然也可以同时指定多个协议,expose是个List。
客户端实现
---
客户端只要支持hessiani协议,都可以进行远程调用我们上面的grails服务。
这里我们还是用grails来调用。
1. 导入接口
可以将服务端的 `src/java` 目录下与rpc相关的java类全部拷贝过来,也可以在服务端生成这几个java类的jar包,然后再导入过来。总之,这些接口必须保证服务端与客户端是一样的(类名、方法相同)。
2. 设置远程rpc service
新建一个grails service,service名必须与服务端的grails service名一致:
java:
class SynchronizeService {
/**
* 远程调用参数
*/
static remote = [
protocol: 'hessian', //rpc协议
iface: ISynchronizeService, //接口class名
// 服务端的url地址为 http://localhost:8081/rpcserver
host: 'localhost', //远端地址
port: '8081', //远端端口
webcontext: 'rpcserver' //webapp的context名称,即url中的名称
]
}
这个service只要包含这些东西就行了,其中重要的是设置好`protocol`,还有`host`与`webcontext`这些值。`iface`是接口的类名,要包含报名,如 foo.bar.ISynchronizeService,类加载器必须能找到的。这个service会在grails启动时自动注入接口相关的代码。
3. 访问远程服务
新建一个controller,并写一个action:
atcion
java:
def testRpc() {
def series = SynchronizeService.syncSeries(1L)
render series.getName()
}
注意到了没,接口的方法会被自动注入进service当中,插件会根据协议来在接口中实现相应的代码。很省事。
当然,客户端可以是任何支持remoting中支持协议的语言、平台。如android、ios。