RMI注意事項

RMI服務接口

提供服務的RMI服務接口必須實現(xiàn)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 <T>
 */
public interface RMIService extends Remote{

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

RMI服務啟動

RMI服務端口

RMI需要兩個端口:

  • 服務開啟端口
Registry registry = LocateRegistry.createRegistry(port);

port端口,用來開啟RMI服務,RMI終端連接需要制定連接此端口

String URL = "rmi://"+host+":"+port+"/rmiservice";
rmiService = (RMIService)Naming.lookup(URL);
  • 服務交互端口
    RMI終端在與RMI服務端建立連接后會需要利用此端口來進行交互, 而此端口在RMI服務器啟動后是隨機生成的,這樣在防火墻穿透時就不好處理, 因為隨機防火墻都不知道對外開放哪個端口了,故在生產環(huán)境下是需要制定此端口的,這樣我們就需要實現(xiàn)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服務抽象也必須靜態(tài)化
    private static RMIService rmiService;
    //RMI服務的實現(xiàn)類必須靜態(tài)化
    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服務的實現(xiàn)類必須靜態(tài)化
            rmiServiceImpl = new RMIServiceImpl();
            //RMI服務抽象也必須靜態(tài)化
            rmiService=(RMIService)UnicastRemoteObject.exportObject(rmiServiceImpl,0); //固定端口設置,配合在RMISocketFactory實現(xiàn)中做處理
            
            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服務抽象也必須靜態(tài)化
  • RMI服務的實現(xiàn)類必須靜態(tài)化
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容