RMI注意事項

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 <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)境下是需要制定此端口的冷尉,這樣我們就需要實現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服務的實現類必須靜態(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服務的實現類必須靜態(tài)化
            rmiServiceImpl = new RMIServiceImpl();
            //RMI服務抽象也必須靜態(tài)化
            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服務抽象也必須靜態(tài)化
  • RMI服務的實現類必須靜態(tài)化
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末雀哨,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子私爷,更是在濱河造成了極大的恐慌雾棺,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衬浑,死亡現場離奇詭異捌浩,居然都是意外死亡,警方通過查閱死者的電腦和手機工秩,發(fā)現死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來促脉,“玉大人坡锡,你說我怎么就攤上這事∶椋” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵迹栓,是天一觀的道長抚芦。 經常有香客問我,道長迈螟,這世上最難降的妖魔是什么叉抡? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮答毫,結果婚禮上褥民,老公的妹妹穿的比我還像新娘。我一直安慰自己洗搂,他們只是感情好消返,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耘拇,像睡著了一般撵颊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惫叛,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天倡勇,我揣著相機與錄音,去河邊找鬼嘉涌。 笑死妻熊,一個胖子當著我的面吹牛,可吹牛的內容都是我干的仑最。 我是一名探鬼主播扔役,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼警医!你這毒婦竟也來了亿胸?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤预皇,失蹤者是張志新(化名)和其女友劉穎侈玄,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體深啤,經...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡拗馒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了溯街。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诱桂。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡洋丐,死狀恐怖,靈堂內的尸體忽然破棺而出挥等,到底是詐尸還是另有隱情友绝,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布肝劲,位于F島的核電站迁客,受9級特大地震影響,放射性物質發(fā)生泄漏辞槐。R本人自食惡果不足惜掷漱,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望榄檬。 院中可真熱鬧卜范,春花似錦、人聲如沸鹿榜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舱殿。三九已至奥裸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沪袭,已是汗流浹背湾宙。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留枝恋,地道東北人创倔。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓嗡害,卻偏偏與公主長得像焚碌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子霸妹,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內容