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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值