Mina 简单案例(客户端与服务端)

Mina封装好了很完善的方法,代码注释的很清楚直接上代码:

      // 创建一个非阻塞的Server端socket,用NIO
            IoAcceptor acceptor = new NioSocketAcceptor();
            // 创建接受数据的过滤器, 处理最简单的字符串传输,Mina 已经为我们提供了                         TextLineCodecFactory
            // 编解码器工厂来对字符串进行编解码处理。
            acceptor.getFilterChain().addLast("logger", new LoggingFilter());
            // 设定这个过滤器将一行一行的读取数据
            acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new SocketCodecFactory()));
            // 然后我们把这个IoHandler 注册到IoService:
            acceptor.setHandler(new TimeServerHandler());
            // 设置读取数据的缓冲区大小
            acceptor.getSessionConfig().setReadBufferSize(2048);
            // 设置10没有消息就进入闲置状态
            acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
            // 绑定端口号
            acceptor.bind(new InetSocketAddress(Constant.PORT_NUMBER));

虽然Mina自己有自己的解码工厂,为了自己的也无需求一般我们会自己建立自己的解码工厂SocketCodecFactory()

public class SocketCodecFactory implements ProtocolCodecFactory {

    private final SocketDecode decoder;

    private final SocketEncode encoder;

    public SocketCodecFactory() {
        decoder = new SocketDecode();
        encoder = new SocketEncode();
    }

    @Override
    public ProtocolDecoder getDecoder(IoSession session) throws Exception {
        return decoder;
    }

    @Override
    public ProtocolEncoder getEncoder(IoSession session) throws Exception {
        return encoder;
    }

}

SocketDecode 这里处理自己的逻辑,根据客户端 发送的数据进行自己业务逻辑操作

public class SocketDecode implements ProtocolDecoder {
    int bufid = 0;

    @Override
    public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
        int playerid = 0;
        playerid = (int) session.getAttribute("PLAYERID", playerid);
        if (playerid > 0) {
            getStutasCode(in);
        }
        // 创建房间 并向客户端返回房间信息
        if (bufid == 1) {
            RoomManage.getInstace().create(playerid);
        }
        // 玩家进入房间 并向客户端返回所有玩家信息
        if (bufid == 2) {
            PBPlayer playerBuf = PBPlayer.parseFrom(in.array());
            RoomManage.getInstace().enter(playerBuf.getRoomId(), new Player(playerBuf.getPlayerId(),
                    playerBuf.getName(), playerBuf.getHeadurl(), playerBuf.getGender(), playerBuf.getScore(), session));
        }
        // 玩家坐下
        if (bufid == 3) {
            PBPlayer playerBuf = PBPlayer.parseFrom(in.array());
            PBSeat pbSeat = PBSeat.parseFrom(in.array());
            RoomManage.getInstace().sitDown(
                    playerBuf.getRoomId(), new Player(playerBuf.getPlayerId(), playerBuf.getName(),
                            playerBuf.getHeadurl(), playerBuf.getGender(), playerBuf.getScore(), session),
                    pbSeat.getSeatId());
        }
        // 玩家离开房间 并向客户端返回此房间的所有信息
        if (bufid == 3) {
            PBPlayer playerBuf = PBPlayer.parseFrom(in.array());
            RoomManage.getInstace().leave(playerBuf.getRoomId(), new Player(playerBuf.getPlayerId(), session));
        }
        // 开始游戏
        if (bufid == 4) {
            PBRoom pbroom = PBRoom.parseFrom(in.array());
            RoomManage.getInstace().roomHashMap.get(pbroom.getRoomId()).begin();
        }

    }

    private void getStutasCode(IoBuffer in) {
        UtilsProtobuf.PButil buf = null;
        try {
            buf = UtilsProtobuf.PButil.parseFrom(in.array());
        } catch (InvalidProtocolBufferException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        bufid = buf.getCode();
    }

    @Override
    public void dispose(IoSession session) throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {
        // TODO Auto-generated method stub

    }

}

里面的逻辑代码是我鞋的简单需求,以供以后查看便于阅读
SocketEncode 当服务端需要向客户端回复消息的时候回走到这个类(out.write(messsage))

public class SocketEncode implements ProtocolEncoder {

    @Override
    public void dispose(IoSession session) throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {

        out.write(message);

    }

}

客户端和服务端Mina基本相同

public class MimaTimeClient {
    public static void main(String[] args) {
        IoConnector connector = new NioSocketConnector();
        connector.getFilterChain().addLast("logger", new LoggingFilter());
        connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(new PrefixedStringCodecFactory(Charset.forName("UTF-8"))));
        connector.setHandler(new TimeClientHander());
        ConnectFuture connectFuture = connector.connect(new InetSocketAddress("192.168.1.124", Constant.PORT_NUMBER));
        // 等待建立连接
        System.out.println("等待建立连接");
        connectFuture.awaitUninterruptibly();
        System.out.println("连接成功");

        IoSession session = connectFuture.getSession();
        PButil.Builder pbutils = PButil.newBuilder();
        pbutils.setCode(1);
        PButil info = pbutils.build();
        byte[] result = info.toByteArray();
        Scanner sc = new Scanner(System.in);

        boolean quit = false;

        while (!quit) {

            String str = sc.next();
            if (str.equalsIgnoreCase("quit")) {
                quit = true;
            }
            session.write(result);
        }

        // 关闭
        if (session != null) {
            if (session.isConnected()) {
                session.getCloseFuture().awaitUninterruptibly();
            }
            connector.dispose(true);
        }

    }

}

其中自定义的界面工厂和服务端相同我就不在重复上传了

PButil.Builder pbutils = PButil.newBuilder();
        pbutils.setCode(1);
        PButil info = pbutils.build();
        byte[] result = info.toByteArray();

这里使用了protobuf用来传送数据,protobuf的使用在我博客中有

protobuf的简单使用
protobuf文件的编写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值