国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

【Mrpc】Demo3 基于netty的服務器和客戶端。

2019-11-11 06:39:36
字體:
來源:轉載
供稿:網友

Demo3實現如下功能,客戶端發送一個Request對象(包含id,方法名,方法參數列表和調用參數列表)到服務端,服務端解析后調用客戶端指定的方法,并返回一個Response對象(包含id,是否異常,異常,返回值)。客戶端和服務端均基于netty實現。代碼已上傳到http://download.csdn.net/detail/mrbcy/9747693

要點解析

netty

這個真的很重要,具體的參考官方的guide吧,寫得通俗易懂。http://netty.io/wiki/user-guide-for-4.x.html#wiki-h3-9

對象的編解碼

對象的編碼和解碼基本使用了Demo1中寫的PRotoStuffUtil工具類,它可以將一個對象轉換成byte[],或者從一個byte[]轉換成一個對象。但是這里還有一個問題,由于tcp協議的特性,對方多次發送的數據我們可能一次性就收到了,或者發送了一次,但是我們分多次收到。為了解決這個問題,我在netty的編碼部分做了處理,在對象的數據之前加了一個字節來存放對象數據的長度。解碼部分也做了相應的處理,先讀取數據的長度,然后等到有足夠的數據再來讀取對象。關鍵代碼如下:

編碼部分:

public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { if(clazz.isInstance(msg)){ byte[] data = ProtostuffUtil.serializer(msg); ByteBuf encoded = ctx.alloc().buffer(data.length+4); encoded.writeInt(data.length); encoded.writeBytes(data); ctx.write(encoded, promise); }}

解碼部分:

@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { // 前4字節記錄長度 if (in.readableBytes() < 4) { return; } in.markReaderIndex(); int dataLength = in.readInt(); if (dataLength < 0) { // 出錯了 ctx.close(); } if (in.readableBytes() < dataLength) { in.resetReaderIndex(); return; } //將ByteBuf轉換為byte[] byte[] data = new byte[dataLength]; in.readBytes(data); //將data轉換成object @SuppressWarnings("unchecked") Object obj = ProtostuffUtil.deserializer(data, clazz); out.add(obj);}

方法調用部分

這里涉及了反射的知識。服務端拿到客戶端傳入的request對象后,根據客戶端指定的方法和參數來調用,然后把結果通過response發送給客戶端。關鍵代碼如下:

RpcResponse response = new RpcResponse();try { RpcRequest request = (RpcRequest) msg; System.out.println("服務器收到調用請求:" + request); response.setId(request.getId()); Method method = SampleServiceImpl.class.getDeclaredMethod(request.getMethodName(), request.getParamTypes()); Object result = method.invoke(serviceImpl, request.getArgs()); response.setResult(result);} catch (Exception e) { response.setSuccess(false); response.setError(e);}

寫到這一步,框架的核心功能已經實現了一大部分,接下來就是用Spring了。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 门头沟区| 苍溪县| 峨眉山市| 出国| 广河县| 漳浦县| 丘北县| 手游| 聊城市| 辉南县| 河北区| 青龙| 通道| 汝阳县| 张家界市| 云安县| 吴川市| 南澳县| 星座| 盐边县| 绥滨县| 嘉峪关市| 台州市| 西乌珠穆沁旗| 阳东县| 托克逊县| 温州市| 桑日县| 通城县| 石渠县| 翁源县| 建瓯市| 历史| 岚皋县| 腾冲县| 南陵县| 越西县| 岳池县| 南开区| 武功县| 资溪县|