java项目后端与web前端的线程部署

1 篇文章 0 订阅

Java后端线程

   在主程序HandleProc中设置4个线程:
//全局时间线程
Runnable timerTask = new MyTimerTask();
cheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
        new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build());
executorService.scheduleAtFixedRate(timerTask, 0, MyTimerTask.TimeInterval, TimeUnit.MILLISECONDS);

//数据库守护线程
Runnable mybatisTask = new MybatisTask();
ScheduledExecutorService executorService1 = new ScheduledThreadPoolExecutor(1,
        new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build());
executorService1.scheduleAtFixedRate(mybatisTask, 0, Config.MybatisInterval, TimeUnit.MILLISECONDS);

//alarm数据库守护线程
Runnable alarmMybatisTask = new AlarmMybatisTask();
ScheduledExecutorService executorService3 = new ScheduledThreadPoolExecutor(1,
        new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build());
executorService3.scheduleAtFixedRate(alarmMybatisTask, 0, Config.AlarmMybatisInterval, TimeUnit.MILLISECONDS);


//数据过期线程
Runnable invalidTask = new InvalidTask();
ScheduledExecutorService executorService2 = new ScheduledThreadPoolExecutor(1,
        new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build());
executorService2.scheduleAtFixedRate(invalidTask, 0, Config.InvalidInterval, TimeUnit.MILLISECONDS);

Java前端web线程

在程序MyWebSocket中设置1个web线程:


@ServerEndpoint(prefix = "netty-websocket")
@Component
public class MyWebSocket {
    private static final Log log = LogFactory.getLog(MyWebSocket.class);
    private ScheduledExecutorService executorService;

    @OnOpen
    public void onOpen(Session session, HttpHeaders headers, ParameterMap parameterMap) throws IOException {
        System.out.println("new connection");
        log.info("web socker new connection");

        String paramValue = parameterMap.getParameter("paramKey");
        System.out.println(paramValue);

        //数据过期线程
        executorService = new ScheduledThreadPoolExecutor(1,
                new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build());
        Runnable webSocketTask = new WebSocketTask(session);
        executorService.scheduleAtFixedRate(webSocketTask, 0, Config.WebsocketInterval, TimeUnit.MILLISECONDS);

    }

    @OnClose
    public void onClose(Session session) throws IOException {
        System.out.println("one connection closed");
        log.error("one connection closed");
        executorService.shutdown();
    }
    }

WebSocketTask


public class WebSocketTask implements Runnable {
    private static final Log log = LogFactory.getLog(WebSocketTask.class);

    private int cycle = 1;
    private Session session;
    private boolean firstFlag = true;
    private Msg.RouteProto routeProtoOrg;

    public WebSocketTask(Session session) {
        this.session = session;
    }

    public int getCycle() {
        return this.cycle;
    }

    public void setCycle() {
        if ((this.cycle - Config.CYCLE_MAX) >= 0) {
            this.cycle = Config.CYCLE_MIN;
        } else {
            this.cycle += 1;
        }
    }


    @Override
    public void run() {
        if (!FlagGlobal.flagMap.get(FlagTyepEnum.Init.getCode())) {
            log.error("初始化未成功~,暂不启动websocketTask线程!");
            return;
        }
        log.error("myWork start ...");
        try {
            int sendFlag = 0;
            StringBuffer typeBuff = new StringBuffer();
            //设置包头
            Msg.MsgProto.Builder msgBuilder = Msg.MsgProto.newBuilder();
            msgBuilder.setVersion(1);
            msgBuilder.setPlatform(1);
            msgBuilder.setCycle(this.getCycle());
            msgBuilder.setTime(System.currentTimeMillis());

            if (this.firstFlag) {
                this.firstFlag = false;
                this.routeProtoOrg = WebGlobal.webRoute;

                //发送全量包
                msgBuilder.setFlag(Config.FULL_STATUS);
                msgBuilder.setType(WebSocketTyepEnum.Full.getCode());
                msgBuilder.setRoute(WebGlobal.webRoute);
                Msg.MsgProto msgProto = msgBuilder.build();
                log.info("web send first full pkg....\n" + msgProto);
                session.sendBinary(msgProto.toByteArray());
                this.setCycle();

                return;
            }

            if (FlagGlobal.flagMap.get(FlagTyepEnum.Full.getCode())) {
                msgBuilder.setFlag(Config.FULL_STATUS);
                msgBuilder.setType(WebSocketTyepEnum.Full.getCode());
                msgBuilder.setRoute(WebGlobal.webRoute);
                Msg.MsgProto msgProto = msgBuilder.build();
                log.info("web send full pkg....\n" + msgProto);
                session.sendBinary(msgProto.toByteArray());
                FlagGlobal.flagMap.put(FlagTyepEnum.Full.getCode(), false);
                this.setCycle();
                return;
            }


    //进路信息模块
    if (WebGlobal.webRoute != null) {
        //webRoute中是最新周期包
        Msg.RouteProto routeProto = WebGlobal.webRoute;
        /**
         *
         *  取 消 包
         */
        if (routeProto != null) {
            //获得取消包protobuf:routeCancel
            Map<String, Object> routeCancel = getCancelData_Route(routeProto);
            if ((Integer) routeCancel.get("code") == Config.SUCC_CODE) {
                sendFlag++;
                Msg.MsgProto.Builder msgBuilder1 = Msg.MsgProto.newBuilder();
                msgBuilder1.setRoute((Msg.RouteProto) routeCancel.get("data"));
                msgBuilder1.setVersion(1);
                msgBuilder1.setPlatform(1);
                msgBuilder1.setCycle(this.getCycle());
                msgBuilder1.setTime(System.currentTimeMillis());
                msgBuilder1.setType(WebSocketTyepEnum.Route.getCode());
                //取消包类型
                msgBuilder1.setFlag(Config.CANCEL_STATUS);
                Msg.MsgProto msgProto = msgBuilder1.build();
                //发送前端
                session.sendBinary(msgProto.toByteArray());
                log.info("web send..cancel..\n" + msgProto);
                this.setCycle();
            }

            /**
             *
             *  变 化 包
             */
            Map<String, Object> routeRes = getChangeData_Route(routeProto);
            if ((Integer) routeRes.get("code") == Config.SUCC_CODE) {
                sendFlag++;
                if (typeBuff.length() == 0) {
                    typeBuff.append(WebSocketTyepEnum.Route.getCode());
                } else {
                    typeBuff.append("," + WebSocketTyepEnum.Route.getCode());
                }
                msgBuilder.setRoute((Msg.RouteProto) routeRes.get("data"));
            }
        }
        this.routeProtoOrg = routeProto;
    }

    log.error("myWork sendFlag= ..." + sendFlag);

    //最终给前端发送整体protobuf
    if (sendFlag > 0) {
        this.setCycle();
        msgBuilder.setType(typeBuff.toString());
        msgBuilder.setFlag(Config.CHG_STATUS);
        Msg.MsgProto msgProto = msgBuilder.build();
        log.info("web send....\n" + msgProto);
        session.sendBinary(msgProto.toByteArray());
    }
} catch (Exception e) {
    log.error("myWork.error,", e);
}
 }




/**
 * 比较进路信息,得到变化包
 *
 * @param routeProto 新周期routeProto
 * @return
 */
private Map<String, Object> getChangeData_Route(Msg.RouteProto routeProto) {
    Map<String, Object> resp = new HashMap<String, Object>();
    //上周期this.routeProtoOrg,新周期routeProto,比较:
    Msg.RouteProto diffRoute = compareData(this.routeProtoOrg, routeProto);
    if (diffRoute == null) {
        resp.put("code", Config.ERR_CODE);
        return resp;
    }
    resp.put("code", Config.SUCC_CODE);
    resp.put("status", Config.CHG_STATUS);
    resp.put("data", diffRoute);
    return resp;
}


/**
 * 比较进路信息,得到取消包
 *
 * @param routeProto 新周期routeProto
 * @return
 */
public Map<String, Object> getCancelData_Route(Msg.RouteProto routeProto) {
    Map<String, Object> resp = new HashMap<String, Object>();
    //上周期this.routeProtoOrg,新周期routeProto,比较:
    Msg.RouteProto diffRoute = cancelData(this.routeProtoOrg, routeProto);
    if (diffRoute == null) {
        resp.put("code", Config.ERR_CODE);
        return resp;
    }
    resp.put("code", Config.SUCC_CODE);
    //添加取消包配置CANCEL_STATUS
    resp.put("cancel", Config.CANCEL_STATUS);
    resp.put("data", diffRoute);
    return resp;
}


/**
 * 比较总进路信息上一次和这一次的包的不同
 *
 * @param last 上一周期
 * @param now  新周期
 * @return
 */
private Msg.RouteProto compareData(Msg.RouteProto last, Msg.RouteProto now) {
    List<Msg.RouteInfo> diffList = compareRouteInfo(last.getListList(), now.getListList());
    if (diffList.size() == 0) {
        return null;
    }
    //新旧周期RouteInfo不相等,变化部分res
    Msg.RouteProto.Builder res = Msg.RouteProto.newBuilder();
    res.setNumber(diffList.size());
    res.addAllList(diffList);
    return res.build();
}


/**
 * 比较总进路新旧周期,得到取消进路
 *
 * @param last 上一周期
 * @param now  新周期
 * @return
 */
public Msg.RouteProto cancelData(Msg.RouteProto last, Msg.RouteProto now) {
    //比较新旧周期的proto的第二层list数据RouteInfo
    List<Msg.RouteInfo> diffList1 = cancelRouteInfo(last.getListList(), now.getListList());
    if (diffList1.size() == 0) {
        return null;
    }
    //新旧周期RouteInfo不相等,变化部分res
    Msg.RouteProto.Builder res = Msg.RouteProto.newBuilder();
    res.setNumber(diffList1.size());
    res.addAllList(diffList1);
    return res.build();
}


/**
 * 比较总进路中RouteInfo,获得取消进路
 *
 * @param old
 * @param now
 * @return
 */
public List<Msg.RouteInfo> cancelRouteInfo(List<Msg.RouteInfo> old, List<Msg.RouteInfo> now) {
    //变化的RouteInfo
    List<Msg.RouteInfo> different = new ArrayList<>();
    //上周期的RouteInfo
    List<Msg.RouteInfo> maxList = old;
    //新周期的RouteInfo
    List<Msg.RouteInfo> minList = now;
    Map<Integer, Integer> map = new HashMap<>(maxList.size());
    Map<Integer, Msg.RouteInfo> mapOrg = new HashMap<>(maxList.size());
    Map<Integer, Msg.RouteInfo> mapDiff = new HashMap<>();

    //遍历上一周期
    for (Msg.RouteInfo routeInfo : maxList) {
        //map存放上周期的RouteInfo
        map.put(routeInfo.getRouteId(), 1);
        //mapOrg存放上周期的RouteInfo
        mapOrg.put(routeInfo.getRouteId(), routeInfo);
    }

    //遍历新周期的map
    for (Msg.RouteInfo routeInfo : minList) {

        /**
         *     获取新周期minList的routeInfo.getRouteId(),判断该id是否在上周期map的key中:
         *     如果该id在上周期,则不为空,将其id又put进map的key,value赋值为2。且continue,直到
         *     该id不在上周期,则为空,将其id值put进mapDiff中。
         *     旧:1(value:1)、2(value:1)、3(value:1)
         *     新:1、2、4
         *
         */
        if (map.get(routeInfo.getRouteId()) != null) {
            // map:1(value:2)、2(value:2)、3(value:1)
            //3(value:1)取消了
            map.put(routeInfo.getRouteId(), 2);
            continue;
        }
        //id为4的放入mapDiff
        mapDiff.put(routeInfo.getRouteId(), routeInfo);
    }

    /**
     *
     *   取消包
     */
    if (map.size() > 0) {
        //遍历map:1(value:2)、2(value:2)、3(value:1)
        for (Map.Entry<Integer, Integer> entryCancel : map.entrySet()) {
            //获取value为1的是取消的
            if (entryCancel.getValue() == 1) {
                Msg.RouteInfo.Builder routeCancel = Msg.RouteInfo.newBuilder();
                routeCancel.setRouteId(entryCancel.getKey());
                different.add(routeCancel.build());
            }
        }
    }
    return different;
}


/**
 * 比较总进路中RouteInfo
 *
 * @param old
 * @param now
 * @return
 */
private List<Msg.RouteInfo> compareRouteInfo(List<Msg.RouteInfo> old, List<Msg.RouteInfo> now) {
    //变化的RouteInfo
    List<Msg.RouteInfo> different = new ArrayList<>();
    //上周期的RouteInfo
    List<Msg.RouteInfo> maxList = old;
    //新周期的RouteInfo
    List<Msg.RouteInfo> minList = now;
    Map<Msg.RouteInfo, Integer> map = new HashMap<>(maxList.size());
    Map<Integer, Msg.RouteInfo> mapOrg = new HashMap<>(maxList.size());
    Map<Integer, Msg.RouteInfo> mapDiff = new HashMap<>();

    //遍历上一周期
    for (Msg.RouteInfo routeInfo : maxList) {
        //map存放上周期的RouteInfo
        map.put(routeInfo, 1);
        //mapOrg存放上周期的RouteInfo
        mapOrg.put(routeInfo.getRouteId(), routeInfo);
    }

    //遍历新周期的map
    for (Msg.RouteInfo routeInfo : minList) {
        //判断上周期的RouteInfo不为空
        if (map.get(routeInfo) != null) {
            //继续map存放新周期的RouteInfo,每次新周期来都有标志
            map.put(routeInfo, 2);
            continue;
        }
        //将新周期的routeInfo存入mapDiff
        mapDiff.put(routeInfo.getRouteId(), routeInfo);
    }

    /**
     *
     *    变化包
     */
    //遍历存有新周期信息的mapDiff
    for (Map.Entry<Integer, Msg.RouteInfo> entry : mapDiff.entrySet()) {
        //判断上周期mapOrg的key是否包含新周期的key
        if (!mapOrg.containsKey(entry.getKey())) {
            //若不包含,新周期中该key对应信息value为新的,将该信息add进变化的RouteInfo
            different.add(entry.getValue());
        }
        //判断上周期mapOrg的key包含了新周期的key,比较同一key对应value的值
        else {
            Msg.RouteInfo.Builder builder = Msg.RouteInfo.newBuilder();
            //同一key,取上周期的RouteInfo
            Msg.RouteInfo orgRouteInfo = mapOrg.get(entry.getKey());
            //同一key,取新周期的RouteInfo
            Msg.RouteInfo nowRouteInfo = entry.getValue();
            //set新周期进路id
            builder.setRouteId(nowRouteInfo.getRouteId());
            //其次,一一判断新周期nowRouteInfo的各个状态是否与上周期orgRouteInfo相等
            if ((nowRouteInfo.getSectionCnt() - orgRouteInfo.getSectionCnt()) != 0) {
                //不相等,set新周期的状态
                builder.setSectionCnt(nowRouteInfo.getSectionCnt());
            }
            if ((nowRouteInfo.getSignalStatus() - orgRouteInfo.getSignalStatus()) != 0) {
                builder.setSignalStatus(nowRouteInfo.getSignalStatus());
            }
            //比较routeInfo中的section的list集合(第三层proto最内层)
            List<Msg.RouteSection> diffRouteSection = compareRouteSection(orgRouteInfo.getSectionsList(), nowRouteInfo.getSectionsList());
            if (diffRouteSection.size() != 0) {
                builder.addAllSections(diffRouteSection);
            }
            different.add(builder.build());
        }
    }
    return different;
}


/**
 * 比较单条进路内 区段信息 状态
 *
 * @param old
 * @param now
 * @return
 */
private List<Msg.RouteSection> compareRouteSection(List<Msg.RouteSection> old, List<Msg.RouteSection> now) {
    List<Msg.RouteSection> sectionDifferent = new ArrayList<>();

    Map<Msg.RouteSection, Integer> sectionMap = new HashMap<>(old.size());
    Map<Integer, Msg.RouteSection> sectionMapOrg = new HashMap<>(now.size());
    Map<Integer, Msg.RouteSection> sectionMapDiff = new HashMap<>();
    //旧周期
    for (Msg.RouteSection routeSection : old) {
        sectionMap.put(routeSection, 1);
        sectionMapOrg.put(routeSection.getSectionNr(), routeSection);
    }
    //新周期
    for (Msg.RouteSection sectionList : now) {
        if (sectionMap.get(sectionList) != null) {
            sectionMap.put(sectionList, 2);
            continue;
        }
        sectionMapDiff.put(sectionList.getSectionNr(), sectionList);
    }
    //遍历新周期
    for (Map.Entry<Integer, Msg.RouteSection> entry : sectionMapDiff.entrySet()) {

        if (!sectionMapOrg.containsKey(entry.getKey())) {
            sectionDifferent.add(entry.getValue());
        } else {
            Msg.RouteSection.Builder sbuilder = Msg.RouteSection.newBuilder();
            //旧
            Msg.RouteSection orgSection = sectionMapOrg.get(entry.getKey());
            //新
            Msg.RouteSection nowSection = entry.getValue();
            sbuilder.setId(nowSection.getId());
            //sbuilder.setSectionNr(nowSection.getSectionNr());
            if ((nowSection.getSectionNr() - orgSection.getSectionNr()) != 0) {
                sbuilder.setSectionNr(nowSection.getSectionNr());
            }
            if ((nowSection.getStatus() - orgSection.getStatus()) != 0) {
                sbuilder.setStatus(nowSection.getStatus());
            }
            sectionDifferent.add(sbuilder.build());
        }
    }
    return sectionDifferent;
}


}

web发送数据

测试地址: http://www.websocket-test.com/
在这里插入图片描述

对应在application.yml中配置websocket测试地址和端口:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值