package com.inspur.netty.handler; import com.inspur.device.domain.vo.SmsbDeviceVo; import com.inspur.device.service.ISmsbDeviceService; import com.inspur.netty.message.push.PushMessageType; import com.inspur.netty.util.NettyConstants; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import java.nio.charset.Charset; /** * 设备鉴权 handler * * @author lihao16 */ @Slf4j public class AuthServerHandler extends ChannelInboundHandlerAdapter { private static final ISmsbDeviceService smsbDeviceService = SpringUtils.getBean(ISmsbDeviceService.class); /** * 当客户端连接服务器完成就会触发该方法 */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { log.info("AuthServerHandler: channelId = " + ctx.channel().id() + ",login channelGroup"); } /** * 此方法现在只会在接收到一条完整的消息时被调用(已被解码器处理过)。 * 框架会自动释放 msg 这个 ByteBuf。 * * @param ctx 上下文 * @param msg 一条完整的、去除了分隔符的消息 */ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { // 解码器已经将 "####" 分隔符去除,这里得到的是完整的消息体 String message = ((ByteBuf) msg).toString(Charset.forName("utf-8")); if (StringUtils.isEmpty(message)) { log.warn("AuthServerHandler: 从 channelId = {} 收到解码后的空消息", ctx.channel().id()); return; } log.info("AuthServerHandler: 接收到客户端的完整消息: {}", message); // 获取消息中的SN 256数据 String identifier = message.split("/")[0]; if (StringUtils.isEmpty(identifier)) { log.warn("AuthServerHandler: 无法从消息 {} 中解析出设备标识", message); // 消息格式不正确,关闭连接 ctx.close(); return; } if (validateDevice(identifier)) { ctx.fireChannelRead(message); } else { // 发送消息鉴权失败 String replayMsg = identifier + PushMessageType.INIT_REPLAY.getValue() + "/fail:auth fail"; ByteBuf byteBuf = Unpooled.copiedBuffer(replayMsg + NettyConstants.DATA_PACK_SEPARATOR, Charset.forName("utf-8")); Channel channel = ctx.channel(); channel.writeAndFlush(byteBuf); ctx.close(); } } private boolean validateDevice(String identifier) { // 根据Mac地址查询设备是否在平台录入 SmsbDeviceVo smsbDeviceVo = smsbDeviceService.getDeviceByIdentifier(identifier); if (null == smsbDeviceVo) { log.info("AuthServerHandler: device not in smsb plus,identifier = " + identifier); return false; } return true; } }