两台服务器之间要进行通信, 可以通过定义消息,开放端口互连这种方式进行, 但是,这种方式但繁琐,每添加一个业务功能, 就要增加一条消息,还要实现消息的处理业务, 这时候使用RMI(远程调用服务)就要简单多了,只需要实现服务端接口, 另一端可以直接调用, 就好像在调用本地代码一样.
这与Webservice类似,但部署起来更简单方便.
服务端使用步骤
1.导入Spring RMI依赖包
2.定义RMI服务接口
/**
* 远程调用服务
* @author SYSTEM
*
*/
public interface RmiService {
/**
* 添加游戏金币
* @param playerId
* @param coin
* @return
*/
public int sendCoin(String senderNic, String playerId, int coin);
/**
* 充值成功
* @param playerId
* @param coin
* @return
*/
public int onExchange(String playerId, int coin);
/**
* 在游戏服发布公告
* @param content
* @return
*/
public int noticeInGameServer(String content);
/**
* 关闭游戏服
* @return
*/
public int shutdown();
3.实现RMI接口
/**
* 远程调用的实现
* @author SYSTEM
*
*/
public class RmiServiceBean implements RmiService{
/**
* 添加游戏金币
* @param recverId
* @param coin
* @return
*/
public int sendCoin(String senderNic, String recverId, int coin){
return MsgConst.RET_SUC;
}
/**
* 在游戏服发布公告
* @param content
* @return
*/
public int noticeInGameServer(String content){
return MsgConst.RET_SUC;
}
@Override
public int shutdown() {
return MsgConst.RET_SUC;
}
@Override
public int onExchange(String playerId, int coin) {
return MsgConst.RET_SUC;
}
}
4.开启RMI远程调用服务
/**
* 启动远程调用服务
*/
private void startRmiService(){
rmiExporter = new RmiServiceExporter();
rmiExporter.setServiceName(ConfigManager.gameServerLoader.getProperties().getRmiServiceName());
rmiExporter.setService(new RmiServiceBean());
rmiExporter.setServiceInterface(RmiService.class);
rmiExporter.setRegistryPort(ConfigManager.gameServerLoader.getProperties().getRmiPort());
try{
rmiExporter.prepare();
}catch(Exception e){
e.printStackTrace();
System.exit(0);
}
LogUtil.println("RMI service start successfully. Port is "+ConfigManager.gameServerLoader.getProperties().getRmiPort());
}
如果要在spring 容器中定义
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id = "userInfoService" class="com.skymr.spring.test.UserInfoServiceBean"></bean>
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<!-- RMI服务名称,可自定义服务名称 -->
<property name="serviceName" value="MessageService" />
<!-- 导出实体 -->
<property name="service" ref="userInfoService" />
<!-- 导出接口 -->
<property name="serviceInterface" value="com.skymr.spring.test.UserInfoService" />
<!-- spring默认使用1099端口 -->
<property name="registryPort" value="1199" />
</bean>
</beans>
客户端调用RMI服务
public class RmiInvoker {
private RmiProxyFactoryBean rmiBean = new RmiProxyFactoryBean();
private RmiService service = null;
public boolean init(String ip, int port, String serviceName) {
rmiBean.setServiceInterface(RmiService.class);
String url = "rmi://%s:%d/%s";
url = String.format(url, ip, port, serviceName);
rmiBean.setServiceUrl(url);
try{
rmiBean.afterPropertiesSet();
}catch(Exception e){
LogUtil.logInfo("RMI初始化异常"+url+","+e.getLocalizedMessage());
return false;
}
service = (RmiService)rmiBean.getObject();
if(service == null){
LogUtil.logInfo("RMI初始化失败"+url);
return false;
}
return true;
}
public RmiService getService(){
return service;
}
}
若通过spring容器使用
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="messageService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://192.168.1.71:1199/MessageService" />
<property name="serviceInterface" value="com.skymr.spring.test.UserInfoService" />
</bean>
</beans>