JAVA Netty开发苏标主动安全附件服务器

  • 苏标是江苏省交通厅2018年发布的道路运输车辆主动安全智能防控系统的平台技术规范,是继部标1078流媒体后这两年最火热的规范,今年深圳展会几乎所有参展商都以主动安全报警作为亮点。
  • 苏标的主动安全实现是通过终端视频算法分析,主动判断出司机驾驶行为是否违反驾驶行为规范,并触发报警,如前向碰撞报警、车道偏离报警、车距过近报警、疲劳驾驶报警、分神驾驶报警、接打电话报警、抽烟报警、驾驶员异常报警、胎压异常报警等。在发生报警的时候,可以上传违章证据到服务器平台,如视频,图片和记录仪数据等。
  • 苏标的报警是通过扩展部标JT808协议0x0200位置上报的附加数据上报的,平台判断附件数量大于0,则下发苏标0x9208附件上传指令让终端把证据文件发到附件服务器。
  • 附件上传的协议使用了2种:(1) 0x1210报警附件信息消息、0x1211文件信息上传、0x1212文件上传完成消息采用部标JT808协议。(2) 文件数据上传采用苏标自定义的格式。


    image.png
  • 因为部标上传的文件有3处:808多媒体文件、1078录像上传FTP、苏标附件,我们将这3块整合在一起,程序起名为file-server,既能处理FTP录像文件又能处理苏标附件,还提供了http文件访问接口给前端。JT808协议解析可以直接复用JT808网关程序的,已经兼容了JT808-2019国标协议。
public class Jt808Message extends BaseMessage {
    /**
     * 消息ID
     */
    private int msgId;

    /**
     * 终端手机号
     */
    private String phoneNumber;

    /**
     * 终端手机号数组
     */
    private byte[] phoneNumberArr;

    /**
     * 协议版本号
     */
    private int protocolVersion;

    /**
     * 消息流水号
     */
    private int msgFlowId;

    /**
     * 是否分包
     */
    private boolean multiPacket;

    /**
     * 版本标识
     */
    private int versionFlag;

    /**
     * 加密方式,0:不加密,1:RSA加密
     */
    private int encryptType;

    /**
     * 消息总包数
     */
    private int packetTotalCount;

    /**
     * 包序号
     */
    private int packetOrder;
}
  • 我们在底层做了一个消息服务处理的provider,每条指令的处理服务在程序启动时自动注册到provider。当每条消息解析成vo传递到netty的handler时,会根据消息ID从provider找到对应的处理服务。市面上开源的或者卖的源码,基本上都用if/else去判断消息ID处理,造成处理类非常庞大,而且很难维护。
@Slf4j
@Sharable
public class Jt808BusinessHandler extends SimpleChannelInboundHandler<Jt808Message> {

    private MessageServiceProvider messageServiceProvider;

    public static final Jt808BusinessHandler INSTANCE = new Jt808BusinessHandler();

    private Jt808BusinessHandler() {
        messageServiceProvider = SpringBeanService.getBean(MessageServiceProvider.class);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Jt808Message msg) throws Exception {
        //获取对应的消息处理器
        int messageId = msg.getMsgId();
        BaseMessageService messageService = messageServiceProvider.getMessageService(messageId);
        ByteBuf msgBodyBuf = Unpooled.wrappedBuffer(msg.getMsgBodyArr());
        try {
            Object result = messageService.process(ctx, msg, msgBodyBuf);
            log.info("收到{}({}),终端手机号:{},消息流水号:{},内容:{}", messageService.getDesc(), CommonUtil.formatMessageId(messageId), msg.getPhoneNumber(), msg.getMsgFlowId(), result);
        } catch (Exception e) {
            Jt808PacketUtil.reply8001(ctx, msg, Jt808ReplyResultEnum.MSG_ERROR);
            printExceptionLog(msg, messageService, e);
        } finally {
            ReferenceCountUtil.release(msgBodyBuf);
        }
    }
}
image.png
  • 文件路径入库的时候,我们把路径用base64编码保存,前端查询时根据base64的路径请求,后台把base64路径解码后直接获取到多媒体文件数据返回前端,这样就省去了查询数据库的步骤。


    image.png
@Api(tags = {"文件管理"})
@RestController
@RequestMapping({"/api/v1/files/"})
public class FileController {
    @Autowired
    private ResourceLoader resourceLoader;

    @ApiOperation("显示文件")
    @GetMapping("/display")
    public ResponseEntity<Resource> show(@ApiParam("路径") @RequestParam String path) {
        try {
            byte[] pathArr = Base64.getDecoder().decode(path);
            String filePath = new String(pathArr, "UTF8");
            log.info("显示文件,路径:{}", filePath);
            return ResponseEntity.ok(resourceLoader.getResource("file:" + filePath));
        } catch (Exception e) {
            return ResponseEntity.notFound().build();
        }
    }
  • 由于file-server做了跨域处理,所以前端直接调用接口没有问题,也可以使用nginx做反向代理,前端页面和接口都用同一个端口,前后端分离一般都用这种方案实现。


    image.png

    image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352

推荐阅读更多精彩内容