rpc系列2-提供上下文RpcContext

實現(xiàn)要求:提供RPC上下文,客戶端可以透傳數(shù)據(jù)給服務端呐伞。

一個應用的基本設計包含幾個重要的角色:

  • 實體域
  • 會話域
  • 服務域

實體域就是應用中抽象出來的組件为严,如Spring中的Bean宫屠,Mybatis中的MappedStatement等匪煌。會話域代表著一次交互過程,如Mybatis中的SqlSession裆悄,而服務域就是組件的功能集矛纹,負責會話域和實體域的生命周期管理,如Spring的ApplicationContext光稼,Shiro的SecurityManager等或南。

現(xiàn)在構造我們這個rpc demo中的會話域角色RpcContext。其主要職責就是負責在一次會話生命周期內(nèi)钟哥,保存迎献、傳遞相關參數(shù)數(shù)據(jù)。會話中的執(zhí)行體就是線程了腻贰,那么理所應當?shù)腞pcContext就應該和當前執(zhí)行線程綁定。很容易想到了ThreadLocal扒秸!

實現(xiàn)如下:

/**
 * rpc上下文
 * 
 * @author wqx
 *
 */
public class RpcContext {
    
    private static ThreadLocal<Map<String,Object>> context = new ThreadLocal<Map<String,Object> >(){
        @Override
        protected Map<String,Object> initialValue() {
            Map<String,Object> m = new HashMap<String,Object>();
            return m;
        }
    };
    
    public static void addAttribute(String key, Object value){
        context.get().put(key,value);
    }
    
    public static Object getAttribute(String key){
        return context.get().get(key);
    }
    
    public static Map<String,Object> getAttributes(){
        return Collections.unmodifiableMap(context.get());
    }
}

RpcContext中的數(shù)據(jù)傳輸載體還是選擇RpcRequest播演,將其包在請求體中即可。如下:

public class RpcRequest implements Serializable
{
    /**
     * 
     */
    private static final long serialVersionUID = -7102839100899303105L;

    //方法名
    private String methodName;
    
    //參數(shù)類型
    private Class<?>[] parameterTypes;
    
    //參數(shù)列表
    private Object[] args;
    
    //參數(shù)
    private Map<String,Object> context;
    

RpcBuilder中在發(fā)送請求前伴奥,需要從當前上下文中獲取數(shù)據(jù)写烤。傳入RpcRequest對象。如下:

RpcRequest request = new RpcRequest(method.getName(), method.getParameterTypes(),args,RpcContext.getAttributes());

同理拾徙,在服務端接收到請求對象RpcRequest之后洲炊,需要將RpcRequest中傳來的數(shù)據(jù)和當前上下文進行關聯(lián)。Handler的run方法修改如下:

        public void run() {
            try{
                ObjectInputStream in = null;
                ObjectOutputStream out = null;
                RpcResponse response = new RpcResponse();
                try {
                    in = new ObjectInputStream(socket.getInputStream());
                    out = new ObjectOutputStream(socket.getOutputStream());

                    Object req = in.readObject();
                    if(req instanceof RpcRequest){
                        RpcRequest rpcRequest = (RpcRequest)req;
                        //關聯(lián)客戶端傳來的上下文數(shù)據(jù)
                        RpcContext.context.set(rpcRequest.getContext());
                        Method method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                        //尼啡。暂衡。。
        }

測試:

業(yè)務接口增加測試方法:
public interface UserService {
    
    /**
     * 上下文測試崖瞭,透明傳輸數(shù)據(jù)
     */
    public Map<String,Object> rpcContextTest();
    
    //狂巢。。书聚。
}
public class UserServiceImpl implements UserService {

    @Override
    public Map<String,Object> rpcContextTest() {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("server","hahaha");
        if(RpcContext.getAttributes() != null )
            map.putAll(RpcContext.getAttributes());
        return map;
    }
    //唧领。藻雌。。
}

客戶端測試代碼:

@Test
public void testRpcContext(){
    RpcContext.addAttribute("client","huhuhu");
    Map<String, Object> res = userService.rpcContextTest();
    Assert.assertEquals(res.get("server"),"hahaha");
    Assert.assertEquals(res.get("client"),"huhuhu");
}

完整代碼

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斩个,一起剝皮案震驚了整個濱河市胯杭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌受啥,老刑警劉巖歉摧,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異腔呜,居然都是意外死亡叁温,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門核畴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膝但,“玉大人,你說我怎么就攤上這事谤草「” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵丑孩,是天一觀的道長冀宴。 經(jīng)常有香客問我,道長温学,這世上最難降的妖魔是什么略贮? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮仗岖,結果婚禮上逃延,老公的妹妹穿的比我還像新娘。我一直安慰自己轧拄,他們只是感情好揽祥,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著檩电,像睡著了一般拄丰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上俐末,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天料按,我揣著相機與錄音,去河邊找鬼鹅搪。 笑死站绪,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的丽柿。 我是一名探鬼主播恢准,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼魂挂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了馁筐?” 一聲冷哼從身側(cè)響起涂召,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎敏沉,沒想到半個月后果正,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡盟迟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年秋泳,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片攒菠。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡迫皱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辖众,到底是詐尸還是另有隱情卓起,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布凹炸,位于F島的核電站戏阅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏啤它。R本人自食惡果不足惜奕筐,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蚕键。 院中可真熱鬧救欧,春花似錦、人聲如沸锣光。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽誊爹。三九已至,卻和暖如春瓢捉,著一層夾襖步出監(jiān)牢的瞬間频丘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工泡态, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留搂漠,地道東北人。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓某弦,卻偏偏與公主長得像桐汤,于是被迫代替她去往敵國和親而克。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)自:http://blog.csdn.net/kesonyk/article/details/50924489 ...
    晴天哥_王志閱讀 24,784評論 2 38
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理怔毛,服務發(fā)現(xiàn)员萍,斷路器,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 國家電網(wǎng)公司企業(yè)標準(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 10,916評論 6 13
  • 兩周前回校拣度,下火車碎绎,換乘地鐵,出站時一對夫婦叫住了我抗果,報出校名問我該搭什么公交筋帖。我轉(zhuǎn)過頭看向他們身后內(nèi)向的學弟,說...
    墨舒朗閱讀 373評論 0 0
  • 積極參與 樂在其中 鍛煉身體 神心放松 景美花香 歡樂融融 汗流浹背 舉足輕重 不虛此行 友情更濃 ----代西猛...
    云淑云卷閱讀 647評論 3 2