package evanq.game.net.manager; import evanq.game.net.AbstractNetConnectionManager; import evanq.game.net.AbstractNettyChannelInitializer; import evanq.game.net.INetConnection; import evanq.game.net.INetConnectionState; import evanq.game.net.NetConnectionEvent; import evanq.game.net.NetConnectionState; import evanq.game.net.NetConnectionType; import evanq.game.net.PacketConst; import evanq.game.net.packets.CHeartBeat; import evanq.game.net.packets.CRequestConnection; import evanq.game.trace.LogSystem; import evanq.game.trace.Trace; /** * 连接状态机应该与连接状态一一相对 * * 一个账号,可以建立多个连接,到服务器。客户端保持多个连接,也对应多个状态机 * * @author Evan cppmain@gmail.com * */ public class ClientNetConnectionFSM extends AbstractNetConnectionFSM { private static Trace logger = LogSystem.getDefaultTrace(ClientNetConnectionFSM.class); public ClientNetConnectionFSM(AbstractNetConnectionManager connectionManager, INetConnection connection) { super(connectionManager,connection); update(new ClientCreatingState()); } @Override public void beat() { if(null == heart)return; CHeartBeat beatPacket = new CHeartBeat(); beatPacket.setPacketId(PacketConst.C_HEART_BEAT); connection.send(beatPacket); } /** * 客户端建立连接 * * @author Evan cppmain@gmail.com * */ class ClientCreatingState implements INetConnectionState{ @Override public void update(INetConnection connection, NetConnectionEvent event) { switch(event){ case CREATE_OK: NetConnectionType channelType = AbstractNettyChannelInitializer.getChannelType(connection); //step 1. 客户端与服务端建立了连接 CRequestConnection requestConnection = new CRequestConnection(); requestConnection.setPacketId(PacketConst.C_CONNECT_REQUEST); requestConnection.setAccessToken(999); requestConnection.setConnectionType(channelType.value()); connection.send(requestConnection); //step 2. 在建立状态进行验证交互 break; case AUTH_OK: //TODO 经过验证之后,才分配特定的编解码器 initHeart(); connection.fsm().update(new ClientOpenState()); connectionManager.addConnection(connection); break; case AUTH_FAILED: break; default: break; } } @Override public NetConnectionState state() { return NetConnectionState.CONNECTING; } } class ClientOpenState implements INetConnectionState{ @Override public void update(INetConnection connection, NetConnectionEvent event) { switch (event) { case PING: if(null != heart){ heart.hearBeat(); } break; case PING_CHECK: if(null!=heart && heart.isDead()){ ClientNetConnectionFSM.this.update(new ClientDelayCloseState()); } break; case DELAYED_CLOSE: break; case CLOSE: break; default: break; } } @Override public NetConnectionState state() { return NetConnectionState.OPEN; } } class ClientDelayCloseState implements INetConnectionState{ @Override public void update(INetConnection connection, NetConnectionEvent event) { } @Override public NetConnectionState state() { return NetConnectionState.BROKEN; } } class ClientCloseState implements INetConnectionState { @Override public void update(INetConnection connection, NetConnectionEvent event) { destoryHeart(); connectionManager.removeConnection(connection); } @Override public NetConnectionState state() { return NetConnectionState.CLOSED; } } }