中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用Springboot和Netty實現rpc

發布時間:2022-02-28 14:45:07 來源:億速云 閱讀:177 作者:iii 欄目:開發技術

這篇文章主要介紹“怎么用Springboot和Netty實現rpc”,在日常操作中,相信很多人在怎么用Springboot和Netty實現rpc問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么用Springboot和Netty實現rpc”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

Springboot、 Netty、動態代理(反射)、反射

項目整體結構如下:

怎么用Springboot和Netty實現rpc

 1.在父項目中引入相關依賴;

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.48.Final</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.58</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>2.0.0-alpha1</version>
        </dependency>

2.服務提供模塊整體結構如下:

怎么用Springboot和Netty實現rpc

 這里重點關注一下 RequestModel  ResponseModel 兩個消息體類,

@Data
@AllArgsConstructor
public class RequestModel {
 
    private String requestId;
    private String serviceName;
    private String methodName;
    private Class[] paramTypes;
    private Object[] paramValues;
 
}
@Data
@AllArgsConstructor
public class ResponseModel {
    private String responseId;
    private String serviceName;
    private String methodName;
    private String code;
    private String data;
}

用于服務端和客戶端的數據傳輸;再者就是關注 ServerChannelInboundHandler 中的 channelRead0() 報文解碼處理;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        StringBuilder sb = null;
        RequestModel result = null;
        try {
            // 報文解析處理
            sb = new StringBuilder();
            result = JSON.parseObject(msg, RequestModel.class);
 
            requestId = result.getRequestId();
            String serviceName = result.getServiceName();
            String methodName = result.getMethodName();
            Class[] paramType = result.getParamTypes();
            Object[] paramValue = result.getParamValues();
            System.out.println(serviceName + "  " + methodName);
            String substring = serviceName.substring(serviceName.lastIndexOf(".") + 1);
            String s = substring.substring(0, 1).toLowerCase() + substring.substring(1);
            Object serviceObject = applicationContext.getBean(s);
            Method method = Class.forName(serviceName).getMethod(methodName, paramType);
            Object returnValue = method.invoke(serviceObject, paramValue);
            ResponseModel responseModel = new ResponseModel(requestId,serviceName,methodName,"200",JSON.toJSONString(returnValue));
            sb.append(JSON.toJSONString(responseModel));
            sb.append("\n");
            System.out.println(sb.toString());
            ctx.writeAndFlush(sb);
        } catch (Exception e) {
            ResponseModel responseModel = new ResponseModel(requestId,"","","500",e.getMessage());
            String errorCode = JSON.toJSONString(responseModel)+"\n";
            log.error(errorCode);
            ctx.writeAndFlush(errorCode);
            log.error("報文解析失敗: " + e.getMessage());
        }
    }

客戶端的模塊代碼如下; 

怎么用Springboot和Netty實現rpc

這里重點關注的是 ClientHandler 類中 channelRead0() 方法的處理

 @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        System.out.println("收到服務端消息: " + msg);
 
        ResponseModel responseModel = JSON.parseObject(msg,ResponseModel.class);
        String responseId = responseModel.getResponseId();
        Promise promise = LocalPromise.promiseMap.remove(responseId);
        if(promise != null){
            String code = responseModel.getCode();
            if(code.equals("200")){
                promise.setSuccess(responseModel.getData());
            }else{
                promise.setFailure(new RuntimeException(responseModel.getData()));
            }
        }
    }

AppStart 類中獲取獲取服務的處理;

private <T> T getProxyService(Class<T> serviceClass) {
        Object service = Proxy.newProxyInstance(serviceClass.getClassLoader(), new Class[]{serviceClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Channel channel = NettyClient.getChannel(host, port);
                RequestModel requestModel = new RequestModel("100001", method.getDeclaringClass().getName(), method.getName(), method.getParameterTypes(), args);
                channel.writeAndFlush(JSON.toJSONString(requestModel) + "\n");
                Promise promise = new DefaultPromise(channel.eventLoop());
                LocalPromise.promiseMap.put(requestModel.getRequestId(), promise);
 
                System.out.println(LocalPromise.promiseMap+">>>>>>>>>>>>");
                promise.await();
                if (promise.isSuccess()) {
                    Class<?> returnType = method.getReturnType();
                    return JSON.toJavaObject(JSON.parseObject(promise.getNow()+""),returnType);
                } else {
                    System.out.println(promise.cause());
                    return promise.cause();
                }
            }
        });
        return (T) service;
    }

 測試結果:

怎么用Springboot和Netty實現rpc

怎么用Springboot和Netty實現rpc

到此,關于“怎么用Springboot和Netty實現rpc”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

两当县| 桐柏县| 定州市| 通化市| 牡丹江市| 安吉县| 涞源县| 通道| 临泉县| 大名县| 宝鸡市| 辽宁省| 富民县| 闸北区| 江永县| 岗巴县| 罗城| 木兰县| 繁昌县| 炎陵县| 阳春市| 武威市| 达孜县| 明星| 昌吉市| 河津市| 科尔| 延庆县| 青铜峡市| 通州区| 桂林市| 华亭县| 丰顺县| 苍山县| 河北省| 唐山市| 安顺市| 大丰市| 华阴市| 道孚县| 基隆市|