JT809协议交通809协议简单实现(Java版)
简介
最近公司有个项⽬需要接收公交公司的实时推送的公交车位置数据。于是就⽤Netty简单实现了JT809协议的部分功能。
服务端(上级平台)主链路
主链路登录请求报⽂解析
主链路登录应答消息
车辆实时车辆定位信息消息报⽂解析
主要代码和使⽤
项⽬结构
解码适配器
package cn.xiuminglee.jt809.protocol;
import cn.xiuminglee.jt809mon.util.CommonUtils;
import cn.xiuminglee.jt809mon.util.CrcUtil;
import cn.xiuminglee.jt809mon.util.PacketDecoderUtils;
import cn.xiuminglee.jt809.packet.JT809BasePacket;
import cn.xiuminglee.jt809.protocol.decoder.DecoderFactory;
import ioty.buffer.ByteBuf;
import ioty.channel.ChannelHandlerContext;
import dec.ByteToMessageDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import static cn.xiuminglee.jt809mon.util.CommonUtils.PACKET_CACHE;
/**
* @Author: Xiuming Lee
* @Describe: 解码适配器
*/
public class JT809DecoderAdapter extends ByteToMessageDecoder {
private static Logger log = Logger(JT809DecoderAdapter.class);
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)throws Exception {
//判断是否有可读的字节
adableBytes()<=0){
return;
}
/
/ 1、进⾏转义
byte[] bytes = PacketDecoderUtils.decoderEscape(in);
decoder// 2、校验crc
if(!CrcUtil.checkCRC(bytes)){
return;
}
// 3、判断是那种类型的数据,交给具体的解码器类完成。
ByteBuf byteBuf = ByteBuf(bytes);
byteBuf.skipBytes(9);
// 获取业务标志
short msgId = adShort();
/
/ 交给具体的解码器
JT809BasePacket packet = null;
try{
packet = Decoder(msgId).decoder(bytes);
}catch(Exception e){
if(e instanceof NullPointerException){
// log.info("没有可⽤的解析器,忽略这条信息!此信息不在业务范围内。");
// 没有可⽤的解析器,忽略这条信息!此信息不在业务范围内。
}else{
<("报⽂解析出错!错误信息:{};报⽂信息:{};",e.getMessage(),(Thread.currentThread().getName()));
}
return;
}
out.add(packet);
}
}
这个解码适配器会根据报⽂的业务标志从DecoderFactory获取具体的解码器去解析报⽂。
所以如果需要扩展,只需要编写相关业务的解码器并添加到DecoderFactory即可。
package cn.xiuminglee.jt809.protocol.decoder;
import cn.xiuminglee.jt809mon.Const;
import java.util.HashMap;
import java.util.Map;
/
**
* @Author: Xiuming Lee
* @Describe: 解码⼯⼚类
*/
public class DecoderFactory {
private static Map<Short,Decoder> DECODER_FACTORY =new HashMap<>();
static{
DECODER_FACTORY.put(Const.BusinessDataType.UP_CONNECT_REQ,new LoginDecoder());
DECODER_FACTORY.put(Const.BusinessDataType.UP_LINKTEST_REQ,new HeartbeatDecoder());
DECODER_FACTORY.put(Const.BusinessDataType.UP_EXG_MSG,new JT809Packet0x1202Decoder()); }
/**
* @param businessDataType 业务数据类型标志
* @return 具体的解码器
*/
public static Decoder getDecoder(short businessDataType){
return (businessDataType);
}
}