Как получить данные кеша из указанного ChannelHandler в Netty? - PullRequest
0 голосов
/ 21 декабря 2018

На сервере при получении запроса входа от каждого клиента я буду кэшировать данные, используя ConcurrentHashMap<String, String>() в методе channelRead. Могу ли я получить значение ConcurrentHashMap<String, String>(), определив публичный метод public synchronized static Map<String, String> getClientMap() в любом месте?И я хочу определить задачу расписания для выполнения операции очистки кэша, данные которого в приведенном выше ConcurrentHashMap<String, String>(), как я могу сделать в Netty?Я пробовал много раз, но не получилось.Это мой код в ChannelHandler:

public class LoginAuthRespHandler extends ChannelInboundHandlerAdapter {

private static final Logger LOGGER = LoggerFactory.getLogger(LoginAuthRespHandler.class);

private static final Map<String, String> nodeCheck = new ConcurrentHashMap<String, String>();

private String[] whiteList = { "127.0.0.1", "192.168.56.1" };


@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    AlarmMessage message = (AlarmMessage) msg;
    //judge the messsge's type
    if (message.getHeader() != null && message.getHeader().getType() == MessageType.LOGIN_REQ.value()) {
        String nodeIndex = ctx.channel().remoteAddress().toString();
        AlarmMessage loginResp = null;

        if (nodeCheck.containsKey(nodeIndex)) {
            loginResp = buildResponse(ResultType.FAIL);
        } else {
            InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
            String ip = address.getAddress().getHostAddress();
            boolean isOK = false;
            for (String WIP : whiteList) {
                if (WIP.equals(ip)) {
                    isOK = true;
                    break;
                }
            }
            loginResp = isOK ? buildResponse(ResultType.SUCCESS) : buildResponse(ResultType.FAIL);
            if (isOK)
                //add a value
                nodeCheck.put(nodeIndex, message.getBody().toString());
                System.out.println(nodeCheck.get(nodeIndex));
        }

        ctx.writeAndFlush(loginResp);
    } else {
        ctx.fireChannelRead(msg);
    }
}

private AlarmMessage buildResponse(ResultType result) {
    AlarmMessage message = new AlarmMessage();
    Header header = new Header();
    header.setType(MessageType.LOGIN_RESP.value());
    message.setHeader(header);
    message.setBody(result.value());
    return message;
}

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    String nodeIndex = ctx.channel().remoteAddress().toString();
    ctx.close();
    if(nodeCheck.containsKey(nodeIndex)){
        nodeCheck.remove(nodeIndex);
    }
}

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    cause.printStackTrace();
    ctx.close();
    ctx.fireExceptionCaught(cause);
}
public static Map<String, String> getNodeCheck() {
    return nodeCheck;
}

}

А это мой код в основной теме:

ScheduledFuture<?> sf = executor.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {

            HashSet<String> clients = new HashSet<>();
            Map<String,String> map = LoginAuthRespHandler.getNodeCheck();
            System.out.println(map.size());

            for (String key:map.keySet()) {

                clients.add(map.get(key));
            }
            //update data
            try{

                MySQLDB.updateClientStatus(clients);

            }catch (Exception e){

                e.printStackTrace();
            }

            //clear map
            map.clear();
            clients.clear();
        }
    },10,10,TimeUnit.SECONDS);
}
...