RMI注意事項

4458 ワード

RMIサービスインタフェース
サービスを提供するRMIサービスインタフェースはRemoteインタフェースを実現しなければならない.
import java.rmi.Remote;
import java.rmi.RemoteException;

import com.google.protobuf.GeneratedMessageLite;
import com.yaowan.h5qipai.protobuf.message.code.Poker.RMIParam;


/**
 * RMI  
 * @author 
 *
 * @param 
 */
public interface RMIService extends Remote{

    public Entity extends GeneratedMessageLite> dispatch(Entity paramEntity )throws RemoteException;
}

RMIサービス起動
RMIサービスポート
RMIには2つのポートが必要です.
  • サービスオープンポート
  • Registry registry = LocateRegistry.createRegistry(port);
    

    portポート、RMIサービスを開くために使用され、RMI端末接続はこのポートに接続する必要がある.
    String URL = "rmi://"+host+":"+port+"/rmiservice";
    rmiService = (RMIService)Naming.lookup(URL);
    
  • サービスインタラクティブポートRMI端末は、RMIサービス側と接続を確立した後、このポートを利用してインタラクティブを行う必要があるが、このポートはRMIサーバの起動後にランダムに生成されるため、ファイアウォールが貫通する際に処理しにくい.ランダムファイアウォールはどのポートを外部に置くか分からないため、生産環境下でこのポートを制定する必要がある.これにより、RMISocketFactoryクラスを実装して、このポート
  • を指定する必要があります.
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.rmi.server.RMISocketFactory;
    
    import com.yaowan.framework.util.LogUtil;
    
    public class RMILocalSocketFactory extends RMISocketFactory {
    
        private int dataPort;
        
        public RMILocalSocketFactory(int dataPort){
            this.dataPort = dataPort;
        }
        @Override
        public ServerSocket createServerSocket(int port) throws IOException {
            if(port == 0){
                port = dataPort;
                LogUtil.info("RMIDataPort: "+port);
            }
            LogUtil.info("RMI createServerSocket: "+port);
            
            return new ServerSocket(port); 
        }
    
        @Override
        public Socket createSocket(String host, int port) throws IOException {
            String key = host+":"+port;
            LogUtil.info("RMI createSocket: "+key);
            return new Socket(host, port);
        }
    }
    

    RMIサービス起動
    import java.net.MalformedURLException;
    import java.rmi.RemoteException;
    import java.rmi.registry.LocateRegistry;
    import java.rmi.registry.Registry;
    import java.rmi.server.RMISocketFactory;
    import java.rmi.server.UnicastRemoteObject;
    
    import org.apache.commons.lang3.exception.ExceptionUtils;
    
    import com.yaowan.framework.core.GlobalConfig;
    import com.yaowan.framework.util.LogUtil;
    
    /**
     * RMI      
     * @author 
     *
     */
    public class RMIServiceServer {
        
        String host;
        private int port;
        private String URL;
        //RMI          
        private static RMIService rmiService;
        //RMI           
        private static RMIService rmiServiceImpl;
        public RMIServiceServer(int port) {
            this.port = port;
            this.host = GlobalConfig.getString("IntranetIP");
            URL = "rmi://"+host+":"+port+"/dispatche";
        }
        /**
         *     RMI  
         */
        public void start() {
            try {
    //          System.setProperty("java.rmi.server.hostname", host);
                
                int dataPort = GlobalConfig.getInt("RMIDataPort");
                if(dataPort == 0){//     ,      
                    dataPort = 19998;
                }
                
                RMISocketFactory.setSocketFactory(new RMILocalSocketFactory(dataPort));
                //RMI           
                rmiServiceImpl = new RMIServiceImpl();
                //RMI          
                rmiService=(RMIService)UnicastRemoteObject.exportObject(rmiServiceImpl,0); //      ,   RMISocketFactory      
                
                System.setProperty("java.rmi.server.hostname",host);
                
                LogUtil.info("Binding server implementation to registry");
                Registry registry = LocateRegistry.createRegistry(port);
                
                registry.rebind("dispatche", rmiService);
    //          Naming.rebind(URL, rmiService);
                LogUtil.info("Waiting for invocations from clients ...");
                LogUtil.info("URL: "+URL);
                
            } catch (RemoteException e) {
                LogUtil.error(ExceptionUtils.getStackFrames(e));
            } catch (MalformedURLException e) {
                LogUtil.error(ExceptionUtils.getStackFrames(e));
            }catch(Exception e){
                LogUtil.error(ExceptionUtils.getStackFrames(e));
            }
        }
    }
    

    注意点:
  • RMIサービス抽象も
  • 静態化する必要がある
  • RMIサービスの実装クラスは、
  • を静態化する必要がある.