package com.jqmobile.core.server.rmi2;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.sql.Connection;
import com.jqmobile.core.server.rmi.IRmiRemote;
import com.jqmobile.core.server.rmi.RmiException;
import com.jqmobile.core.server.rmi.RmiRemote;
import com.jqmobile.core.server.rmi.RmiUser;
import com.jqmobile.core.server.rmi.test.IRMITest;
import com.jqmobile.core.server.rmi.test.RMIDirectSocketFactory;
import com.jqmobile.core.server.rmi.test.User;
import com.jqmobile.core.server.service.ServiceFactory;
import com.jqmobile.core.utils.thread.AsyncTask;
/**
* <p>远程服务调用</p>
*
* <p>Copyright: 版权所有 (c) 2002 - 2015<br>
* Company: 久其</p>
*
* @author modi qq:411051729
* @version 2014年4月1日
*/
public class RemoteServiceFactory extends ServiceFactory{
private final static RMIDirectSocketFactory rmiFactory = new RMIDirectSocketFactory();
public static void main(String[] args) throws IOException {
// RemoteManagerFactory.setRemoteIp("10.2.5.86");
final RemoteServiceFactory rsf = new RemoteServiceFactory();
RmiUser user = new RmiUser();
user.setUserName("test");
user.setPassword("123455abcdefg!@#$");
rsf.setUser(user);
File f = new File("/Users/modi/Documents/myjob/rmiTest.txt");
if(!f.exists())
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
final RandomAccessFile rf = new RandomAccessFile(f, "rw");
rf.seek(rf.length());
// final FileWriter fw = new FileWriter(f);
for(int i=0; i<0; i++){
AsyncTask<Void, Void> task = new AsyncTask<Void, Void>(){
@Override
protected Void doInBackground(Void... params) throws Throwable {
test(rsf, rf);
System.out.println(index++);
return null;
}
};
task.execute();
}
test(rsf, null);
try {
Thread.sleep(30000);
rf.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static int index = 0;
private static void test(RemoteServiceFactory rsf, RandomAccessFile rf) throws IOException {
IRMITest r = rsf.instanceService(IRMITest.class);
User u = r.login("userName", "password");
final String str = u+"========\t\t\t"+rsf.getSession()+"\n";
if(null != rf) rf.writeChars(str);
else System.out.println(str);
}
private String session;//远程相应回话机制
private String remoteIp="127.0.0.1";
private Integer remotePort=9700;
private RmiUser user;
private RemoteServiceFactory(){
}
public RemoteServiceFactory(String ip){
this(ip, 9700);
}
public RemoteServiceFactory(String ip, int port){
this.remoteIp = ip;
this.remotePort = port;
}
public String getSession() {
return session;
}
public void setUser(RmiUser user) {
this.user = user;
}
//=============================================================
@Override
protected InvocationHandler getInvocationHandler(Class<?> c) {
return new RemoteBaseInvocationHandler(c, this);
}
@Override
public Connection newConnection() {
return null;
}
//=============================================================
static final class RemoteBaseInvocationHandler implements InvocationHandler{
private Class<?> c;
private RemoteServiceFactory f;
RemoteBaseInvocationHandler(Class<?> c, RemoteServiceFactory remoteManagerFactory){
this.c=c;
this.f = remoteManagerFactory;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String ip = f.remoteIp;//==null?"127.0.0.1":f.remoteIp;
int port = f.remotePort;//==null?9700:f.remotePort;
try{
Registry r = LocateRegistry.getRegistry(ip, port, rmiFactory);
IRmiRemote remote = (IRmiRemote) r.lookup(IRmiRemote.class.getName());
int autoLoginCount = 3;
return request(method, args, remote, autoLoginCount);
}catch(Throwable e){
throw new RemoteException("未能找到远程代理对象,请检查是否注册远程代理,远程地址或端口是否正确", e);
}
}
private Object request(Method method, Object[] args, IRmiRemote remote,
int autoLoginCount) throws RemoteException, Throwable {
if(null == f.session){
try{
f.session = login(remote);
}catch(RmiException e){
System.out.println(e.getCode());
return null;
}
}
RmiRemote rmi = new RmiRemote();
rmi.setManagerClass(c.getName());
rmi.setMethod(method.getName());
rmi.setArgs(args);
rmi.setSession(f.session);
try {
return remote.invoke(rmi);
} catch (Throwable e) {
Throwable e1 = e;
if(e1 instanceof ServerException){
e1 = ((ServerException)e1).getCause();
}
if(e1 instanceof RmiException){
int code = ((RmiException) e1).getCode();
switch (code) {
case RmiException.RMI_RequestIP_Error:
break;
case RmiException.RMI_AboveMaxConn_Error:
break;
case RmiException.RMI_Password_Error:
break;
case RmiException.RMI_NotFoundUsername_Error:
break;
case RmiException.RMI_Session_Error:
f.session = null;
if(autoLoginCount-->0)
request(method, args, remote, autoLoginCount);
break;
default:
break;
}
}
throw e;
// e.printStackTrace();
}
}
private String login(IRmiRemote remote) throws RemoteException {
RmiRemote rmi = new RmiRemote();
rmi.setManagerClass("com.jqmobile.core.server.rmi.IRmiLogin");
rmi.setMethod("login");
rmi.setArgs(f.user);
try{
return (String) remote.invoke(rmi);
}catch(Throwable e){
Throwable e1 = e;
while(e1 instanceof UndeclaredThrowableException || e1 instanceof InvocationTargetException || e1 instanceof ServerException){
e1 = e1.getCause();
}
if(e1 instanceof RmiException){
throw (RmiException)e1;
}else if(e1 instanceof RemoteException){
throw (RemoteException)e1;
}else{
throw new RemoteException("内部方法调用异常", e1);
}
}
}
}
}