java nio 網路架構實現

來源:互聯網
上載者:User

標籤:

 

maven項目
https://github.com/solq360/common

  • 鏈式編/解碼
  • 鏈路層鏈式處理
  • 管道管理socket
  • 多協議處理非常方便
  • 仿netty NioEventLoop 單線程串列處理

========
侍加功能 :

  • 自動化編/解碼
  • rpc 介面增強使用
簡單聊天例子server

TestNioServer

//建立session管理工廠ISessionFactory sessionFactory = new SessionFactory();//建立編/解碼管理ICoderParserManager coderParserManager = new CoderParserManager();//註冊包編/解碼,處理業務coderParserManager.register(CoderParser.valueOf("server chat", PackageDefaultCoder.valueOf(), new ChatTestServerHandle()));//建立ServerSocket 執行個體ServerSocket serverSocket=ServerSocket.valueOf(SocketChannelConfig.valueOf(6969), 10,20,coderParserManager, sessionFactory);//啟動服務serverSocket.start();//阻塞當前線程serverSocket.sync();//關閉處理serverSocket.stop();
client

TestNioClient
傳統方式串連

//建立編/解碼管理 ICoderParserManager coderParserManager = new CoderParserManager(); //註冊包編/解碼,處理業務coderParserManager.register(CoderParser.valueOf("chat", PackageDefaultCoder.valueOf(), new ChatHandle()));//建立ClientSocket 執行個體final ClientSocket clientSocket = ClientSocket.valueOf(SocketChannelConfig.valueOf(6969), new SocketPool("client", null), coderParserManager, new EmptyHandle());//類比串連之後發送訊息Timer timer = new Timer();timer.schedule(new TimerTask() {    @Override    public void run() {clientSocket.send("串連伺服器成功");System.out.println("send ");this.cancel();    }}, 1000);//啟動服務clientSocket.start();//阻塞當前線程clientSocket.sync();//關閉處理clientSocket.stop();

伺服器方式串連

//建立session管理工廠ISessionFactory sessionFactory = new SessionFactory();//建立編/解碼管理 ICoderParserManager coderParserManager = new CoderParserManager(); //註冊包編/解碼,處理業務coderParserManager.register(CoderParser.valueOf("chat", PackageDefaultCoder.valueOf(), new ChatHandle()));//建立ClientSocket 執行個體final ServerSocket serverSocket = ServerSocket.valueOf(SocketChannelConfig.valueOf(8888), 10, 20, coderParserManager, sessionFactory);//類比串連之後發送訊息Timer timer = new Timer();timer.schedule(new TimerTask() {    @Override    public void run() {System.out.println("registerClientSocket");//主動串連伺服器ClientSocket clientSocket = serverSocket.registerClient(SocketChannelConfig.valueOf(6969));clientSocket.send("串連伺服器成功");this.cancel();    }}, 1000);//啟動服務serverSocket.start();//阻塞當前線程serverSocket.sync();//關閉處理serverSocket.stop();
源碼實現過程

鏈式編/解碼

  • 由 多個 ICoder 輸入/輸出轉換處理
  • CoderParser 類組裝多個 ICoder
  • 編/碼處理器 注意優先順序

  • nio read -> packageCoder -> link coders -> handle

  • handle write -> link coders -> packageCoder -> nio write

  • 由 ICoderParserManager 管理調用處理
public interface ICoderParserManager {    /**     * 解碼處理     *      * @return CoderResult     * */    CoderResult decode(ByteBuffer buffer, ICoderCtx ctx);    /**     * 編碼處理     * */    ByteBuffer encode(Object message, ICoderCtx ctx);    void error(ByteBuffer buffer, ICoderCtx ctx);    /** 註冊 編/碼處理器 */    void register(CoderParser coderParser);}

其中核心
decode
encode

  @Override    public CoderResult decode(ByteBuffer buffer, ICoderCtx ctx) {final SocketChannelCtx socketChannelCtx = (SocketChannelCtx) ctx;final ClientSocket clientSocket = socketChannelCtx.getClientSocket();for (CoderParser coderParser : coderParsers.values()) {    final IPackageCoder packageCoder = coderParser.getPackageCoder();    final ICoder<?, ?>[] linkCoders = coderParser.getCoders();    final IHandle handle = coderParser.getHandle();    Object value = null;    synchronized (buffer) {// 已解析完if (socketChannelCtx.getCurrPackageIndex() >= buffer.limit()) {    return CoderResult.valueOf(ResultValue.UNFINISHED);}// 包協議處理if (!packageCoder.verify(buffer, ctx)) {    continue;}// 包解析value = packageCoder.decode(buffer, ctx);if (value == null) {    // 包未讀完整    return CoderResult.valueOf(ResultValue.UNFINISHED);}    }    // 鏈式處理    if (linkCoders != null) {for (ICoder coder : linkCoders) {    value = coder.decode(value, ctx);    if (value == null) {throw new CoderException("解碼出錯 : " + coder.getClass());    }}    }    // 業務解碼處理    value = handle.decode(value, ctx);    clientSocket.readBefore(socketChannelCtx, value);    handle.handle(value, ctx);    clientSocket.readAfter(socketChannelCtx, value);    return CoderResult.valueOf(ResultValue.SUCCEED);}return CoderResult.valueOf(ResultValue.NOT_FIND_CODER);    }    @Override    public ByteBuffer encode(Object message, ICoderCtx ctx) {for (CoderParser coderParser : coderParsers.values()) {    final IPackageCoder packageCoder = coderParser.getPackageCoder();    final ICoder<?, ?>[] linkCoders = coderParser.getCoders();    final IHandle handle = coderParser.getHandle();    // 業務檢查    if (!handle.verify(message, ctx)) {continue;    }    // 業務編碼處理    Object value = handle.encode(message, ctx);    // 鏈式處理    if (linkCoders != null) {for (int i = linkCoders.length - 1; i >= 0; i--) {    ICoder coder = linkCoders[i];    value = coder.encode(value, ctx);    if (value == null) {throw new CoderException("編碼出錯 : " + coder.getClass());    }}    }    // 打包訊息處理    value = packageCoder.encode(value, ctx);    if (value != null) {return (ByteBuffer) value;    }    throw new CoderException("編碼出錯  :" + packageCoder.getClass());}throw new CoderException("未找到編/解碼處理器 ");   }   
  • 半包/帖包處理 : AbstractISocketChannel doRead方法摘要,根據解碼返回的狀態做處理。
  • 半包:當不是完成狀態時,繼續解碼,從最後一次包索引開始處理
  • 帖包:當完成包解碼移動包索引,等侍下輪解碼處理

       boolean run = true;    // 粘包處理    while (run) {ByteBuffer cpbuffer = socketChannelCtx.coderBegin();cpbuffer.mark();CoderResult coderResult = coderParserManager.decode(cpbuffer, socketChannelCtx);switch (coderResult.getValue()) {case SUCCEED:    break;case NOT_FIND_CODER:    final int readySize = socketChannelCtx.getWriteIndex() - socketChannelCtx.getCurrPackageIndex();    final int headLimit = 255;    if (readySize >= headLimit) {throw new CoderException("未找到編/解碼處理器 ");    }    run = false;    break;case UNFINISHED:case UNKNOWN:case ERROR:default:    run = false;    // TODO throw    break;}  }

http://www.cnblogs.com/solq/p/4585496.html

java nio 網路架構實現(轉)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.