From d02e424ef36e86d9ef5729f2dad97f9fd23d6beb Mon Sep 17 00:00:00 2001 From: nico Date: Wed, 7 Nov 2018 14:55:48 +0800 Subject: [PATCH] Handler client normal exit and abnormal exit situations --- .../server/event/ServerEventListener.java | 26 +++++++++++ .../ServerEventListener_CODE_PLAYER_EXIT.java | 34 ++++++++++++++ .../handler/DefaultChannelInitializer.java | 5 +-- .../server/handler/TransferHandler.java | 45 +++++++++++++++---- 4 files changed, 97 insertions(+), 13 deletions(-) create mode 100644 landlords-server/src/main/java/org/nico/ratel/landlords/server/event/ServerEventListener_CODE_PLAYER_EXIT.java diff --git a/landlords-server/src/main/java/org/nico/ratel/landlords/server/event/ServerEventListener.java b/landlords-server/src/main/java/org/nico/ratel/landlords/server/event/ServerEventListener.java index 16af28c..6cc17b1 100644 --- a/landlords-server/src/main/java/org/nico/ratel/landlords/server/event/ServerEventListener.java +++ b/landlords-server/src/main/java/org/nico/ratel/landlords/server/event/ServerEventListener.java @@ -1,6 +1,10 @@ package org.nico.ratel.landlords.server.event; +import java.util.HashMap; +import java.util.Map; + import org.nico.ratel.landlords.entity.ServerTransferData; +import org.nico.ratel.landlords.enums.ServerEventCode; import io.netty.channel.Channel; @@ -8,4 +12,26 @@ public interface ServerEventListener { public void call(Channel channel, ServerTransferData serverTransferData); + public final static Map LISTENER_MAP = new HashMap<>(); + + final static String LISTENER_PREFIX = "org.nico.ratel.landlords.server.event.ServerEventListener_"; + + public static ServerEventListener get(ServerEventCode code){ + ServerEventListener listener = null; + try { + if(ServerEventListener.LISTENER_MAP.containsKey(code)){ + listener = ServerEventListener.LISTENER_MAP.get(code); + }else{ + String eventListener = LISTENER_PREFIX + code.name(); + Class listenerClass = (Class) Class.forName(eventListener); + listener = listenerClass.newInstance(); + ServerEventListener.LISTENER_MAP.put(code, listener); + } + return listener; + }catch(ClassNotFoundException | InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + return listener; + } + } diff --git a/landlords-server/src/main/java/org/nico/ratel/landlords/server/event/ServerEventListener_CODE_PLAYER_EXIT.java b/landlords-server/src/main/java/org/nico/ratel/landlords/server/event/ServerEventListener_CODE_PLAYER_EXIT.java new file mode 100644 index 0000000..f586212 --- /dev/null +++ b/landlords-server/src/main/java/org/nico/ratel/landlords/server/event/ServerEventListener_CODE_PLAYER_EXIT.java @@ -0,0 +1,34 @@ +package org.nico.ratel.landlords.server.event; + +import org.nico.ratel.landlords.channel.ChannelUtils; +import org.nico.ratel.landlords.entity.ClientSide; +import org.nico.ratel.landlords.entity.Room; +import org.nico.ratel.landlords.entity.ServerTransferData; +import org.nico.ratel.landlords.enums.ClientEventCode; +import org.nico.ratel.landlords.server.ServerContains; + +import io.netty.channel.Channel; + +public class ServerEventListener_CODE_PLAYER_EXIT implements ServerEventListener{ + + @Override + public void call(Channel channel, ServerTransferData serverTransferData) { + + ClientSide clientSide = ServerContains.CLIENT_SIDE_MAP.get(serverTransferData.getClientId()); + Room room = ServerContains.ROOM_MAP.get(clientSide.getRoomId()); + + if(room != null) { + for(ClientSide client: room.getClientSideList()) { + if(client.getId() != clientSide.getId()) { + ChannelUtils.pushToClient(client.getChannel(), ClientEventCode.CODE_SHOW_OPTIONS, null, clientSide.getNickname() + " exited, room dissolve!!"); + }else { + ChannelUtils.pushToClient(client.getChannel(), ClientEventCode.CODE_SHOW_OPTIONS, null, "you exited, room dissolve!!"); + } + client.init(); + } + } + + ServerContains.ROOM_MAP.remove(room.getId()); + } + +} diff --git a/landlords-server/src/main/java/org/nico/ratel/landlords/server/handler/DefaultChannelInitializer.java b/landlords-server/src/main/java/org/nico/ratel/landlords/server/handler/DefaultChannelInitializer.java index b583c6a..0b1c5d7 100644 --- a/landlords-server/src/main/java/org/nico/ratel/landlords/server/handler/DefaultChannelInitializer.java +++ b/landlords-server/src/main/java/org/nico/ratel/landlords/server/handler/DefaultChannelInitializer.java @@ -7,6 +7,7 @@ import org.nico.ratel.landlords.enums.ClientStatus; import org.nico.ratel.landlords.print.SimplePrinter; import org.nico.ratel.landlords.server.ServerContains; +import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.serialization.ClassResolvers; @@ -24,10 +25,6 @@ public class DefaultChannelInitializer extends ChannelInitializer ch.pipeline().addLast(new ObjectEncoder()); ch.pipeline().addLast(new TransferHandler()); - ClientSide clientSide = new ClientSide(ServerContains.getClientId(), ClientStatus.TO_CHOOSE, ch); - ServerContains.CLIENT_SIDE_MAP.put(clientSide.getId(), clientSide); - SimplePrinter.println("A client connects to the server:" + clientSide.getId()); - ChannelUtils.pushToClient(ch, ClientEventCode.CODE_CONNECT, clientSide); } } diff --git a/landlords-server/src/main/java/org/nico/ratel/landlords/server/handler/TransferHandler.java b/landlords-server/src/main/java/org/nico/ratel/landlords/server/handler/TransferHandler.java index bcf9200..f149e52 100644 --- a/landlords-server/src/main/java/org/nico/ratel/landlords/server/handler/TransferHandler.java +++ b/landlords-server/src/main/java/org/nico/ratel/landlords/server/handler/TransferHandler.java @@ -1,9 +1,18 @@ package org.nico.ratel.landlords.server.handler; +import java.net.InetSocketAddress; + +import org.nico.ratel.landlords.channel.ChannelUtils; +import org.nico.ratel.landlords.entity.ClientSide; import org.nico.ratel.landlords.entity.ServerTransferData; +import org.nico.ratel.landlords.enums.ClientEventCode; +import org.nico.ratel.landlords.enums.ClientStatus; import org.nico.ratel.landlords.enums.ServerEventCode; +import org.nico.ratel.landlords.print.SimplePrinter; +import org.nico.ratel.landlords.server.ServerContains; import org.nico.ratel.landlords.server.event.ServerEventListener; +import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; @@ -11,6 +20,19 @@ public class TransferHandler extends ChannelInboundHandlerAdapter{ private final static String LISTENER_PREFIX = "org.nico.ratel.landlords.server.event.ServerEventListener_"; + + + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + Channel ch = ctx.channel(); + + ClientSide clientSide = new ClientSide(((InetSocketAddress)ch.remoteAddress()).getPort(), ClientStatus.TO_CHOOSE, ch); + clientSide.setNickname(String.valueOf(clientSide.getId())); + ServerContains.CLIENT_SIDE_MAP.put(clientSide.getId(), clientSide); + SimplePrinter.println("A client connects to the server:" + clientSide.getId()); + ChannelUtils.pushToClient(ch, ClientEventCode.CODE_CONNECT, clientSide); + } + @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { @@ -20,18 +42,23 @@ public class TransferHandler extends ChannelInboundHandlerAdapter{ ServerEventCode code = serverTransferData.getCode(); if(code != null) { - String eventListener = LISTENER_PREFIX + code.name(); - - try { - Class listenerClass = (Class) Class.forName(eventListener); - ServerEventListener listener = listenerClass.newInstance(); - listener.call(ctx.channel(), serverTransferData); - }catch(ClassNotFoundException e) { - e.printStackTrace(); - } + ServerEventListener.get(code).call(ctx.channel(), serverTransferData); } } } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if(cause instanceof java.io.IOException) { + ClientSide client = ServerContains.CLIENT_SIDE_MAP.get(((InetSocketAddress)ctx.channel().remoteAddress()).getPort()); + if(client != null) { + SimplePrinter.println(client.getNickname() + " exit"); + ServerEventListener.get(ServerEventCode.CODE_PLAYER_EXIT).call(ctx.channel(), new ServerTransferData<>(client.getId(), client.getRoomId(), ServerEventCode.CODE_PLAYER_EXIT, null)); + } + } + } + + }