Apache mina 入門(三) —— 客戶端同步通訊

經過之前兩篇文章,
Apache mina 入門(一)— 基礎知識
Apache Mina 入門 (二)—— 異步通信機制
我們對mina 有一個基本的瞭解:mina是個異步通信框架,對於服務端開發,長連接、異步通信使用mina非常便捷。但也有需求,可能需要使用短連接,即每次連接都需要以下四個步驟:連接-發送-接收-斷開。
使用短連接的mina 客戶端不再需要IOHandler的messageReceived方法去處理業務數據,而是變換成在在短連接中,接受消息後進行業務數據處理。如何做到呢?我們只需要設置mina的UseReadOperation屬性爲true。
服務端代碼不需改動。看Apache Mina 入門 (二)—— 異步通信機制這篇文章即可。

同步客戶端代碼

/**
 * mina 客戶端同步通訊
 * 原理:mina異步通訊是建立有效的長連接,客戶端通訊在長連接中進行,
 * 對於mina客戶端同步操作來說,長連接變換爲短連接,即客戶端的每次操作都需要建立連接,發送消息,接收消息,斷開連接
 * @author liuc
 * @date 2017-12-20
 *
 */
public class ClientTest {

    public static void main(String[] args) throws MinaConnectTimeoutException, MinaReadTimeoutException {
        //連接對象
        NioSocketConnector connector = new NioSocketConnector();
        //設置連接超時時間
        connector.setConnectTimeoutMillis(30000L);
        //添加過濾器
        connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(new com.onion.mina.client.ByteArrayCodecFactory()));
        SocketSessionConfig cfg = connector.getSessionConfig();
        //實現同步的mina客戶端必須設置UseReadOperation屬性爲true
        cfg.setUseReadOperation(true);
        IoSession session = null;

        connector.setDefaultRemoteAddress(new InetSocketAddress("127.0.0.1", 8888));// 設置默認訪問地址
        //加入重連機制,重連5次,如果重連不上,則拋出異常
        for (int num = 0;num < 5; num++) {
            try {
                ConnectFuture future = connector.connect();
                future.awaitUninterruptibly(); // 等待連接創建成功
                session = future.getSession(); // 獲取會話
                if (session.isConnected()) {
                    System.out.println("連接服務端"
                            + "127.0.0.1"
                            + ":"
                            + 8888
                            + "[成功]"
                            + ",,時間:"
                            + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                                    .format(new Date()));
                    break;
                }
            } catch (RuntimeIoException e) {
                System.out.println(
                        "連接服務端"
                                + "127.0.0.1"
                                + ":"
                                + 8888
                                + "失敗"
                                + ",,時間:"
                                + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                                        .format(new Date())
                                + ", 連接SOCKET服務異常,請檢查SOCKET端口、IP是否正確,MSG服務是否啓動,異常內容:"
                                + e.getMessage());
                try {
                    Thread.sleep(1000);// 連接失敗後,重連間隔5s
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                throw new MinaConnectTimeoutException("連接SOCKET服務異常,請檢查SOCKET端口、IP是否正確,MSG服務是否啓動");
            }
        }

        if(!session.isConnected()){
            System.out.println(
                    "連接服務端"
                            + "127.0.0.1"
                            + ":"
                            + 8888
                            + "失敗"
                            + ",,時間:"
                            + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                                    .format(new Date())
                            + ", 連接SOCKET服務異常,請檢查SOCKET端口、IP是否正確,MSG服務是否啓動,");
            // 讀超時
            throw new MinaConnectTimeoutException("連接SOCKET服務異常,請檢查SOCKET端口、IP是否正確,MSG服務是否啓動");
        }
        // 現在已實現了連接,接下來就是發送-接收-斷開了
        try {
            BaseMessageForServer message = new BaseMessageForServer();
            String content = "hello world!";
            CRC32 crc = new CRC32();
            try {
                crc.update(content.getBytes("GBK"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            message.setFuncid(5);
            message.setPacketIdCode(10000);
            message.setContent(content);
            message.setCheckCode(crc.getValue());
            message.setLength(content.getBytes().length);
            // 發送
            session.write(message).awaitUninterruptibly();
            doRead(session);
        } finally {
            // 斷開
            session.close(true);
            session.getService().dispose();
            connector.dispose();
        }
    }

    public static void doRead(IoSession session) throws MinaReadTimeoutException {
        // 接收
        ReadFuture readFuture = session.read();
        if (readFuture.awaitUninterruptibly(10000,
                TimeUnit.SECONDS)) {
            // System.out.println("客戶端收到消息:" + message);
            Object obj = readFuture.getMessage();

            if(obj instanceof BaseMessageForClient){
                BaseMessageForClient client = (BaseMessageForClient) obj;
                System.out.println("客戶端收到消息:" + client.toString());
                if (client.getFuncid() == 4) {
                    //收到心跳包
                    System.out.println("收到心跳包");
                    session.write("1111");
                }
            }
        } else {
            // 讀超時
            throw new MinaReadTimeoutException("從socket中讀取數據超時,請檢查MSG服務端是否正常");
        }
    }



}

使用該客戶端即可進行測試。代碼源碼下載地址:http://download.csdn.net/download/u012151597/10166224

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章