smart-socket文檔地址git
http://smartsocket.mydoc.io/?t=260338程序員
碼雲地址:編程
https://gitee.com/smartboot/smart-socketsession
smart(百度翻譯:聰明的;敏捷的;漂亮的;整齊的),從爲項目起名開始,便對其寄予了厚望。專一於通訊組件的研究與發展,摒棄一切大而全的解決方案,僅提供小而美的基礎服務。不管您是從事IOT、IM、RPC,仍是其他通訊領域的開發工做,相信smart-socket都是很是酷的選擇。若是要用一句話來爲smart-socket打call,那就是:碰見smart-socket,你就已經贏在起跑線了。 框架
JDK7雖然已經發布很長一段時間了,但開源社區對於其AIO的新特性貌似並不熱情。對於通訊方面的技術訴求,彷佛你們都習慣於Netty、Mina。「Stop Trying to Reinvent the Wheel」不要重複造輪子,幾乎每一個程序員都被灌輸過這個概念,理所固然的沉浸在各自的溫馨區,享受着開源社區提供的各項技術支撐。舉個跟本文相契合的例子,若是工做中遇到通訊相關的需求,廣大Java程序員腦海裏首先想到的必然是Netty或Mina,即使從未接觸過Netty/Mina,但在內心認定只有這兩個框架才能解決本身面臨的問題。這樣的現狀可能歸咎於如今咱們太急躁,工做的壓力導致沒時間給本身充電,尤爲是那種不經常使用且稍微有點深度的技術點,已經沒心力再去細細琢磨了。所幸還有一批好學的程序員在工做之餘作着一些看似平凡的事,踏踏實實專研這些技術點並做出一些小小的做品,同時爲開源社區注入新鮮血液。目前碼雲上已知的Java AIO項目有tio、Voovan、baseio以及本文的主角:smart-socket,這幾個做品還無任何一款能造成足夠的影響力被廣大Javaer承認,但經過開源的推廣與磨練,相信將來AIO的開源環境會比如今更加繁榮。socket
smart-socket立項之初便已嚴苛的要求進行開發,追求各方面都達到極致。首先,smart-socket是個很是輕量級的項目,只有依賴log4j2做爲項目的日誌組件。smart-socket發佈的jar包僅僅20KB,簡潔的接口設計能夠很是方便的在業務中接入通訊服務。不過咱們更指望看到的是接觸到smart-socket的朋友能夠將其做爲學習Java Socket編程的素材,若是smart-socket能在這方面給予您一絲幫助,那我便會絕對本身作了一件有意義的事。ide
官方指南假設您已瞭解ByteBuffer,並對Socket編程具有必定基礎。若是您剛開始接觸Socket,將smart-socket做爲您的第一步可能不是個好的決定。學習
smart-socket已上傳至Maven倉庫,使用前須要向其引入您的項目工程中。ui
<!-- https://mvnrepository.com/artifact/org.smartboot.socket/aio-core --> <dependency> <groupId>org.smartboot.socket</groupId> <artifactId>aio-core</artifactId> <version>1.3.2</version> </dependency>
基於smart-socket進行通訊服務的開發,主要有三個步驟:this
接下來咱們會經過一個簡單例子來演示如何經過smart-socket開發服務端與客戶端程序。爲簡化操做,服務端與客戶端交互的數據爲一個整型數據。
正常狀況下服務端與客戶端通訊共用同一套協議規則,所以咱們只需編寫一份協議編解碼實現便可。以下所示,協議編解碼的須要實現接口Protocol。
public class IntegerProtocol implements Protocol<Integer> { private static final int INT_LENGTH = 4; @Override public Integer decode(ByteBuffer data, AioSession<Integer> session, boolean eof) { if (data.remaining() < INT_LENGTH) return null; return data.getInt(); } @Override public ByteBuffer encode(Integer s, AioSession<Integer> session) { ByteBuffer b = ByteBuffer.allocate(INT_LENGTH); b.putInt(s); b.flip(); return b; } }
上述代碼很簡單,一個整數的長度爲4byte,因此只要長度大於等於4,咱們就能解析到一個整數。
業務消息的處理須要實現接口MessageProcessor
,該接口只有兩個方法:process
,stateEvent
。其中 stateEvent用於定義AioSession狀態機的監控與處理。process則會處理每個接收到的業務消息。
public class IntegerServerProcessor implements MessageProcessor<Integer> { @Override public void process(AioSession<Integer> session, Integer msg) { Integer respMsg = msg + 1; System.out.println("接受到客戶端數據:" + msg + " ,響應數據:" + (respMsg)); try { session.write(respMsg); } catch (IOException e) { e.printStackTrace(); } } @Override public void stateEvent(AioSession<Integer> session, StateMachineEnum stateMachineEnum, Throwable throwable) { } }
public class IntegerClientProcessor implements MessageProcessor<Integer> { private AioSession<Integer> session; @Override public void process(AioSession<Integer> session, Integer msg) { System.out.println("接受到服務端響應數據:" + msg); } @Override public void stateEvent(AioSession<Integer> session, StateMachineEnum stateMachineEnum, Throwable throwable) { switch (stateMachineEnum) { case NEW_SESSION: this.session = session; break; default: System.out.println("other state:" + stateMachineEnum); } } public AioSession<Integer> getSession() { return session; } }
public class IntegerServer { public static void main(String[] args) { AioQuickServer server = new AioQuickServer() .bind(8888) .setProtocol(new IntegerProtocol()) .setProcessor(new IntegerServerProcessor()); try { server.start(); } catch (IOException e) { e.printStackTrace(); } } }
public class IntegerClient { public static void main(String[] args) throws Exception { IntegerClientProcessor processor=new IntegerClientProcessor(); AioQuickClient aioQuickClient=new AioQuickClient() .connect("localhost",8888) .setProtocol(new IntegerProtocol()) .setProcessor(processor); aioQuickClient.start(); processor.getSession().write(1); Thread.sleep(1000); aioQuickClient.shutdown(); } }