如何从Netty中指定的ChannelHandler获取缓存数据?

时间:2018-12-21 08:40:55

标签: java netty

在服务器中,当接收到每个客户端的请求登录时,我将缓存数据  在方法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);
}

0 个答案:

没有答案