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