diff --git a/jsowell-common/src/main/java/com/jsowell/common/core/domain/ebike/EBikeDataProtocol.java b/jsowell-common/src/main/java/com/jsowell/common/core/domain/ebike/EBikeDataProtocol.java new file mode 100644 index 000000000..38062174c --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/core/domain/ebike/EBikeDataProtocol.java @@ -0,0 +1,73 @@ +package com.jsowell.common.core.domain.ebike; + +import com.google.common.primitives.Bytes; +import com.jsowell.common.util.BytesUtil; +import lombok.Data; + +/** + * 云快充数据模板 + */ +@Data +public class EBikeDataProtocol { + /** + * 包头 3字节 + */ + private byte[] head; + + /** + * 数据长度 2字节 + */ + private byte[] length; + + /** + * 物理id 4字节 + */ + private byte[] physicalId; + + /** + * 消息id 2字节 + */ + private byte[] messageId; + + /** + * 命令 1字节 + */ + private byte[] command; + + /** + * 消息体 N字节 + */ + private byte[] msgBody; + + /** + * 帧校验域 2字节 + */ + private byte[] checksum; + + public EBikeDataProtocol(byte[] msg) { + // 起始标志 + this.head = BytesUtil.copyBytes(msg, 0, 3); + // 数据长度 + this.length = BytesUtil.copyBytes(msg, 3, 2); + // 物理id + this.physicalId = BytesUtil.copyBytes(msg, 5, 4); + // 消息id + this.messageId = BytesUtil.copyBytes(msg, 9, 2); + // 命令 + this.command = BytesUtil.copyBytes(msg, 11, 1); + // 消息体 + this.msgBody = BytesUtil.copyBytes(msg, 12, msg.length - 14); + // 帧校验域 + this.checksum = new byte[]{msg[msg.length - 2], msg[msg.length - 1]}; + } + + /** + * 转换为十六进制字符串 + * + * @return 报文 + */ + public String getHEXString() { + byte[] bytes = Bytes.concat(this.head, this.length, this.physicalId, this.messageId, this.command, this.msgBody, this.checksum); + return BytesUtil.binary(bytes, 16); + } +} diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/decoder/CustomDecoder.java b/jsowell-netty/src/main/java/com/jsowell/netty/decoder/CustomDecoder.java deleted file mode 100644 index 3ea0044c8..000000000 --- a/jsowell-netty/src/main/java/com/jsowell/netty/decoder/CustomDecoder.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.jsowell.netty.decoder; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToMessageDecoder; -import io.netty.handler.codec.CorruptedFrameException; - -import java.util.List; - -public class CustomDecoder extends ByteToMessageDecoder { - private static final byte START_FLAG = (byte) 0x68; - - @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - // 检查可读数据长度是否大于等于起始标志符和数据长度字段的长度 - if (in.readableBytes() >= 3) { - // 标记当前读取位置 - in.markReaderIndex(); - // 读取起始标志符 - byte startFlag = in.readByte(); - // 检查起始标志符是否正确 - if (startFlag != START_FLAG) { - // 如果不正确,重置读取位置,并抛出异常 - in.resetReaderIndex(); - throw new CorruptedFrameException("Invalid start flag: " + startFlag); - } - // 读取数据长度 - byte length = in.readByte(); - // 检查可读数据长度是否大于等于数据长度字段的值 - if (in.readableBytes() >= length) { - // 读取完整数据包 - ByteBuf frame = in.readBytes(length + 2); // 包括校验位 - out.add(frame); - } else { - // 如果可读数据长度不够,重置读取位置,并等待下一次读取 - in.resetReaderIndex(); - } - } - } -} diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/AbstractEBikeHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/AbstractEBikeHandler.java index fbad52604..d0c8ce70f 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/AbstractEBikeHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/AbstractEBikeHandler.java @@ -2,6 +2,7 @@ package com.jsowell.netty.handler.electricbicycles; import com.google.common.primitives.Bytes; import com.jsowell.common.constant.CacheConstants; +import com.jsowell.common.core.domain.ebike.EBikeDataProtocol; import com.jsowell.common.core.domain.ykc.YKCDataProtocol; import com.jsowell.common.core.domain.ykc.YKCFrameTypeCode; import com.jsowell.common.core.redis.RedisCache; @@ -9,7 +10,6 @@ import com.jsowell.common.enums.ykc.PileChannelEntity; import com.jsowell.common.util.BytesUtil; import com.jsowell.common.util.CRC16Util; import com.jsowell.common.util.DateUtils; -import com.jsowell.pile.domain.ebike.AbsEBikeMessage; import io.netty.channel.ChannelHandlerContext; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; @@ -26,23 +26,25 @@ public abstract class AbstractEBikeHandler implements InitializingBean { * 执行逻辑 * 有应答 */ - public abstract byte[] supplyProcess(Class msg, ChannelHandlerContext ctx); + public byte[] supplyProcess(EBikeDataProtocol dataProtocol, ChannelHandlerContext ctx) { + throw new UnsupportedOperationException(); + } /** * 组装应答的结果 - * @param ykcDataProtocol 请求数据 + * @param dataProtocol 请求数据 * @param messageBody 消息体 * @return 应答结果 */ - protected byte[] getResult(YKCDataProtocol ykcDataProtocol, byte[] messageBody) { + protected byte[] getResult(EBikeDataProtocol dataProtocol, byte[] messageBody) { // 起始标志 - byte[] head = ykcDataProtocol.getHead(); + byte[] head = dataProtocol.getHead(); // 序列号域 - byte[] serialNumber = ykcDataProtocol.getSerialNumber(); + byte[] serialNumber = dataProtocol.getPhysicalId(); // 加密标志 - byte[] encryptFlag = ykcDataProtocol.getEncryptFlag(); + byte[] encryptFlag = dataProtocol.getMessageId(); // 请求帧类型 - byte[] requestFrameType = ykcDataProtocol.getFrameType(); + byte[] requestFrameType = dataProtocol.getCommand(); // 应答帧类型 byte[] responseFrameType = YKCFrameTypeCode.PlatformAnswersRelation.getResponseFrameTypeBytes(requestFrameType); diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/GetServerTimeHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/GetServerTimeHandler.java index 31cbec0e1..1edddd2c4 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/GetServerTimeHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/GetServerTimeHandler.java @@ -1,8 +1,8 @@ package com.jsowell.netty.handler.electricbicycles; -import com.jsowell.pile.domain.ebike.AbsEBikeMessage; -import com.jsowell.pile.domain.ebike.EBikeCommandEnum; +import com.jsowell.common.core.domain.ebike.EBikeDataProtocol; import com.jsowell.netty.factory.EBikeOperateFactory; +import com.jsowell.pile.domain.ebike.EBikeCommandEnum; import io.netty.channel.ChannelHandlerContext; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -28,7 +28,7 @@ public class GetServerTimeHandler extends AbstractEBikeHandler { * @param ctx */ @Override - public byte[] supplyProcess(Class msg, ChannelHandlerContext ctx) { + public byte[] supplyProcess(EBikeDataProtocol dataProtocol, ChannelHandlerContext ctx) { return new byte[0]; } } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java index 5e7bbec2c..2fef34e72 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/HeartbeatHandler.java @@ -1,8 +1,8 @@ package com.jsowell.netty.handler.electricbicycles; -import com.jsowell.pile.domain.ebike.EBikeCommandEnum; +import com.jsowell.common.core.domain.ebike.EBikeDataProtocol; import com.jsowell.netty.factory.EBikeOperateFactory; -import com.jsowell.pile.domain.ebike.AbsEBikeMessage; +import com.jsowell.pile.domain.ebike.EBikeCommandEnum; import io.netty.channel.ChannelHandlerContext; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -24,11 +24,11 @@ public class HeartbeatHandler extends AbstractEBikeHandler { * 执行逻辑 * 有应答 * - * @param msg + * @param dataProtocol * @param ctx */ @Override - public byte[] supplyProcess(Class msg, ChannelHandlerContext ctx) { + public byte[] supplyProcess(EBikeDataProtocol dataProtocol, ChannelHandlerContext ctx) { return new byte[0]; } } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java index a6ac55ee1..730fa8c4f 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/RegistrationHandler.java @@ -1,8 +1,8 @@ package com.jsowell.netty.handler.electricbicycles; -import com.jsowell.pile.domain.ebike.AbsEBikeMessage; -import com.jsowell.pile.domain.ebike.EBikeCommandEnum; +import com.jsowell.common.core.domain.ebike.EBikeDataProtocol; import com.jsowell.netty.factory.EBikeOperateFactory; +import com.jsowell.pile.domain.ebike.EBikeCommandEnum; import io.netty.channel.ChannelHandlerContext; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -28,7 +28,7 @@ public class RegistrationHandler extends AbstractEBikeHandler { * @param ctx */ @Override - public byte[] supplyProcess(Class msg, ChannelHandlerContext ctx) { + public byte[] supplyProcess(EBikeDataProtocol dataProtocol, ChannelHandlerContext ctx) { return new byte[0]; } } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java index 858e5fc0b..8c5ad68bf 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/handler/electricbicycles/SettlementUploadHandler.java @@ -1,8 +1,8 @@ package com.jsowell.netty.handler.electricbicycles; -import com.jsowell.pile.domain.ebike.AbsEBikeMessage; -import com.jsowell.pile.domain.ebike.EBikeCommandEnum; +import com.jsowell.common.core.domain.ebike.EBikeDataProtocol; import com.jsowell.netty.factory.EBikeOperateFactory; +import com.jsowell.pile.domain.ebike.EBikeCommandEnum; import io.netty.channel.ChannelHandlerContext; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -24,11 +24,12 @@ public class SettlementUploadHandler extends AbstractEBikeHandler { * 执行逻辑 * 有应答 * - * @param msg + * @param dataProtocol * @param ctx */ @Override - public byte[] supplyProcess(Class msg, ChannelHandlerContext ctx) { - return new byte[0]; + public byte[] supplyProcess(EBikeDataProtocol dataProtocol, ChannelHandlerContext ctx) { + return null; } + } diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerChannelInitializer.java b/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerChannelInitializer.java index a94749fd7..4e4cb6edc 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerChannelInitializer.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerChannelInitializer.java @@ -1,11 +1,10 @@ package com.jsowell.netty.server.electricbicycles; -import com.jsowell.netty.decoder.MessageDecode; -import com.jsowell.netty.decoder.MessageEncode; import com.jsowell.netty.decoder.StartAndLengthFieldFrameDecoder; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.bytes.ByteArrayDecoder; import io.netty.handler.timeout.IdleStateHandler; import org.springframework.stereotype.Component; @@ -22,8 +21,10 @@ public class ElectricBicyclesServerChannelInitializer extends ChannelInitializer protected void initChannel(SocketChannel channel) throws Exception { ChannelPipeline pipeline = channel.pipeline(); pipeline.addLast("frameDecoder", new StartAndLengthFieldFrameDecoder()); - pipeline.addLast("decoder", new MessageDecode()); - pipeline.addLast("encoder", new MessageEncode()); + // pipeline.addLast("decoder", new MessageDecode()); + // pipeline.addLast("encoder", new MessageEncode()); + pipeline.addLast("decoder", new ByteArrayDecoder()); + pipeline.addLast("encoder", new ByteArrayDecoder()); //读超时时间设置为10s,0表示不监控 pipeline.addLast(new IdleStateHandler(60, 0, 0, TimeUnit.SECONDS)); pipeline.addLast("handler", chargingPileHandler); diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerHandler.java b/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerHandler.java index 65e0aef56..d41825c99 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerHandler.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/server/electricbicycles/ElectricBicyclesServerHandler.java @@ -1,8 +1,9 @@ package com.jsowell.netty.server.electricbicycles; import com.alibaba.fastjson2.JSON; +import com.google.common.collect.Lists; import com.jsowell.netty.service.electricbicycles.EBikeBusinessService; -import com.jsowell.pile.domain.ebike.AbsEBikeMessage; +import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; @@ -11,7 +12,9 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -19,16 +22,38 @@ import java.util.concurrent.TimeUnit; @ChannelHandler.Sharable @Slf4j @Component -public class ElectricBicyclesServerHandler extends SimpleChannelInboundHandler { +public class ElectricBicyclesServerHandler extends SimpleChannelInboundHandler { private final Map responseFutureMap = new ConcurrentHashMap<>(); + private final List notPrintFrameTypeList = Lists.newArrayList("0x03"); + @Autowired private EBikeBusinessService eBikeService; @Override - protected void channelRead0(ChannelHandlerContext ctx, AbsEBikeMessage msg) throws Exception { - log.info("收到消息, channelId:{}, msg:{}", ctx.channel().id().toString(), JSON.toJSONString(msg)); + protected void channelRead0(ChannelHandlerContext ctx, Object message) throws Exception { + Channel channel = ctx.channel(); + log.info("收到消息, channelId:{}, msg:{}", channel.id().toString(), JSON.toJSONString(message)); + byte[] msg = (byte[]) message; + + // 处理数据 + byte[] response = eBikeService.process(msg, ctx); + if (Objects.nonNull(response)) { + // 响应客户端 + ByteBuf buffer = ctx.alloc().buffer().writeBytes(response); + // this.channelWrite(channel.id(), buffer); + ctx.writeAndFlush(buffer); + // if (!CollectionUtils.containsAny(notPrintFrameTypeList, frameType)) { + // // 应答帧类型 + // byte[] responseFrameTypeBytes = YKCFrameTypeCode.PlatformAnswersRelation.getResponseFrameTypeBytes(frameTypeBytes); + // String responseFrameType = YKCUtils.frameType2Str(responseFrameTypeBytes); + // log.info("【>>>>>平台响应消息>>>>>】channel:{}, 响应帧类型:{}, 响应帧名称:{}, 原帧类型:{}, 原帧名称:{}, 序列号域:{}, response:{}", + // channel.id(), responseFrameType, YKCFrameTypeCode.getFrameTypeStr(responseFrameType), + // frameType, YKCFrameTypeCode.getFrameTypeStr(frameType), serialNumber, + // BytesUtil.binary(response, 16)); + // } + } } public String sendCommandAndWaitForResponse(Channel channel, String command, long timeout) throws InterruptedException { diff --git a/jsowell-netty/src/main/java/com/jsowell/netty/service/electricbicycles/impl/EBikeBusinessServiceImpl.java b/jsowell-netty/src/main/java/com/jsowell/netty/service/electricbicycles/impl/EBikeBusinessServiceImpl.java index 00a33e808..571f4ad9b 100644 --- a/jsowell-netty/src/main/java/com/jsowell/netty/service/electricbicycles/impl/EBikeBusinessServiceImpl.java +++ b/jsowell-netty/src/main/java/com/jsowell/netty/service/electricbicycles/impl/EBikeBusinessServiceImpl.java @@ -1,13 +1,13 @@ package com.jsowell.netty.service.electricbicycles.impl; -import com.jsowell.common.core.domain.ykc.YKCDataProtocol; +import com.jsowell.common.core.domain.ebike.EBikeDataProtocol; import com.jsowell.common.core.domain.ykc.YKCFrameTypeCode; import com.jsowell.common.enums.ykc.PileChannelEntity; import com.jsowell.common.enums.ykc.PileConnectorDataBaseStatusEnum; +import com.jsowell.common.util.BytesUtil; import com.jsowell.common.util.StringUtils; -import com.jsowell.common.util.YKCUtils; -import com.jsowell.netty.factory.YKCOperateFactory; -import com.jsowell.netty.handler.yunkuaichong.AbstractYkcHandler; +import com.jsowell.netty.factory.EBikeOperateFactory; +import com.jsowell.netty.handler.electricbicycles.AbstractEBikeHandler; import com.jsowell.netty.service.electricbicycles.EBikeBusinessService; import com.jsowell.pile.service.OrderBasicInfoService; import com.jsowell.pile.service.PileConnectorInfoService; @@ -33,16 +33,15 @@ public class EBikeBusinessServiceImpl implements EBikeBusinessService { @Override public byte[] process(byte[] msg, ChannelHandlerContext ctx) { - if (!YKCUtils.checkMsg(msg)) { - // 校验不通过,丢弃消息 - return null; - } - YKCDataProtocol ykcDataProtocol = new YKCDataProtocol(msg); + EBikeDataProtocol ykcDataProtocol = new EBikeDataProtocol(msg); // 获取帧类型 - String frameType = YKCUtils.frameType2Str(ykcDataProtocol.getFrameType()); + String command = BytesUtil.bin2HexStr(ykcDataProtocol.getCommand()); // 获取业务处理handler - AbstractYkcHandler invokeStrategy = YKCOperateFactory.getInvokeStrategy(frameType); - return invokeStrategy.supplyProcess(ykcDataProtocol, ctx); + AbstractEBikeHandler invokeStrategy = EBikeOperateFactory.getInvokeStrategy(command); + if (invokeStrategy != null) { + return invokeStrategy.supplyProcess(ykcDataProtocol, ctx); + } + return null; } @Override