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

来源:互联网 发布:去掉下划线php 编辑:程序博客网 时间:2024/05/17 08:11

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
原创粉丝点击