websocket功能

master
liuqingkun 3 years ago
parent 1b1832f2f6
commit 8dcbdf8da9
  1. 76
      src/main/java/org/springblade/common/cache/business/CarInfoCache.java
  2. 196
      src/main/java/org/springblade/modules/business/controller/CommonApiController.java
  3. 8
      src/main/java/org/springblade/modules/business/entity/BusLine.java
  4. 2
      src/main/java/org/springblade/modules/business/mapper/BusLineMapper.xml
  5. 7
      src/main/java/org/springblade/modules/business/service/IStationHintService.java
  6. 39
      src/main/java/org/springblade/modules/business/service/impl/PublishService.java
  7. 42
      src/main/java/org/springblade/modules/business/service/impl/StationHintServiceImpl.java
  8. 38
      src/main/java/org/springblade/modules/business/vo/CarInfoVO.java
  9. 217
      src/main/java/org/springblade/modules/job/CarInfoTask.java
  10. 6
      src/main/java/org/springblade/modules/websocket/controller/WebSocketController.java
  11. 22
      src/main/java/org/springblade/modules/websocket/handler/WebsocketHandler.java

@ -0,0 +1,76 @@
package org.springblade.common.cache.business;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springblade.common.constant.BusinessConstant;
import org.springblade.common.utils.HttpClientUtils;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.modules.business.entity.CarAdmin;
import org.springblade.modules.business.service.ICarAdminService;
public class CarInfoCache {
// cache name
private static final String CACHE_LIVE_CAR = "live:car:";
private static final String PUSH = "push";
private static final String DATA = "data";
// cache key
private static final String CAR_NO = "car-no";
private static final String STATUS = "status";
private static final String ALL_CAR_DATA = "all";
public static String getPushCarNo() {
return CacheUtil.get(CACHE_LIVE_CAR, PUSH, CAR_NO, () -> {
String url = "http://42.192.165.208:8000/device/currentPush";
String res = HttpClientUtils.doGet(url);
JSONObject json = JSON.parseObject(res);
JSONObject data = json.getJSONObject("data");
String pushStatus = (String) data.get("pushStatus");
String deviceId = (String) data.get("deviceId");
CarAdmin carAdmin = SpringUtil.getBean(ICarAdminService.class).
getOne(Wrappers.<CarAdmin>lambdaQuery().eq(CarAdmin::getReceiverId, deviceId));
String carNo = Func.isEmpty(carAdmin) ? "" : carAdmin.getName();
return carNo;
}, BusinessConstant.TENANT_MODE);
}
public static void setPushCarNo(String carNo) {
CacheUtil.put(CACHE_LIVE_CAR, PUSH, CAR_NO, carNo, BusinessConstant.TENANT_MODE);
}
public static String getPushStatus() {
return CacheUtil.get(CACHE_LIVE_CAR, PUSH, STATUS, () -> {
String url = "http://42.192.165.208:8000/device/currentPush";
String res = HttpClientUtils.doGet(url);
JSONObject json = JSON.parseObject(res);
JSONObject data = json.getJSONObject("data");
String pushStatus = (String) data.get("pushStatus");
String deviceId = (String) data.get("deviceId");
return pushStatus;
}, BusinessConstant.TENANT_MODE);
}
public static void setPushStatus(String status) {
CacheUtil.put(CACHE_LIVE_CAR, PUSH, STATUS, status, BusinessConstant.TENANT_MODE);
}
public static String getAllCarData() {
return CacheUtil.get(CACHE_LIVE_CAR, DATA, ALL_CAR_DATA, () -> {
return "";
}, BusinessConstant.TENANT_MODE);
}
public static void setAllCarData(String allCarData) {
CacheUtil.put(CACHE_LIVE_CAR, DATA, ALL_CAR_DATA, allCarData, BusinessConstant.TENANT_MODE);
}
}

@ -7,6 +7,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.beetl.core.util.ArrayMap;
import org.springblade.common.cache.business.BusLineCache;
import org.springblade.common.cache.business.CarInfoCache;
import org.springblade.common.cache.business.SiteListCache;
import org.springblade.common.constant.BusinessConstant;
import org.springblade.common.constant.CommonConstant;
@ -76,61 +77,12 @@ public class CommonApiController extends BladeController {
CarAdmin carAdmin = carAdminService.getOne(Wrappers.<CarAdmin>lambdaQuery().eq(CarAdmin::getReceiverId, clientId));
String carNo = Func.isEmpty(carAdmin) ? "" : carAdmin.getName();
redisTemplate.opsForValue().set("car-current-number", carNo);
redisTemplate.opsForValue().set("set-current-Facility-stat" + carNo, carStat);
CarInfoCache.setPushCarNo(carNo);
CarInfoCache.setPushStatus(carStat);
publishService.publishToWeb(carNo, carStat);
return R.status(true);
}
/**
* 设置车牌号
*
* @return
*/
@GetMapping("set-car-stat")
public R setCarStat(@RequestParam String carNo, @RequestParam String carStat) {
redisTemplate.opsForValue().set("set-current-Facility-stat" + carNo, carStat);
publishService.publishToWeb(carNo, carStat);
return R.status(true);
}
/**
* 设置车牌号
*
* @return
*/
@GetMapping("set-car-stat-v2")
public R setCarStatV2(@RequestParam String carNo, @RequestParam String carStat) {
redisTemplate.opsForValue().set("car-current-stat" + carNo, carStat);
return R.status(true);
}
/**
* 设置车牌号
*
* @return
*/
@GetMapping("set-car-no")
public R setCarNo(String carNo) {
redisTemplate.opsForValue().set("car-current-number", carNo);
return R.status(true);
}
/**
* 获取车牌号
*
* @return
*/
@GetMapping("get-car-no")
public R getCarNo() {
String carNo = (String) redisTemplate.opsForValue().get("car-current-number");
if (Func.isBlank(carNo)) {
carNo = "鲁F08953D";
}
return R.data(carNo);
}
/**
* 获取车速
*
@ -228,9 +180,6 @@ public class CommonApiController extends BladeController {
siteMsgMap.put("type", "after");
snameList.add(siteMsgMap);
}
// if (Func.isNotEmpty(nextSite3)) {
// snameList.add(nextSite3.getSname());
// }
// 计算当前车辆与前一站和后一站的距离
double pass = 0;
@ -323,146 +272,7 @@ public class CommonApiController extends BladeController {
}
}
return R.data(resultMap);
}
/**
* 获取所有实时的车辆信息
*
* @return
*/
@ApiOperation(value = "获取所有实时的车辆信息", notes = "传入id和busLine")
@GetMapping("/get-all-car-info")
public R getAllCarInfo() {
return R.data(carInfoService.getAllCarInfo());
}
/**
* 获取实时车辆站点信息
*/
@GetMapping("/get-current-info")
public R getCurrentInfo(@RequestParam String carNo) {
CarInfoVO info = carInfoService.getCarInfo(carNo);
if (Func.isEmpty(info)) {
return R.fail("未获取到车辆信息, 请检查车是否已掉线");
}
List<SiteInfoVO> siteList = SiteListCache.getSiteList(info.getLinename(), info.getUpordown());
int nextSiteIdx = Integer.parseInt(info.getInorder());
if (BusinessConstant.CAR_STAT_IN.toString().equals(info.getNowstate())) {
nextSiteIdx -= 1;
}
// 下一站
List<Map<String, String>> snameList = new ArrayList<>();
SiteInfoVO nextSite = nextSiteIdx < siteList.size() ? siteList.get(nextSiteIdx) : null;
SiteInfoVO nextSite2 = (nextSiteIdx + 1) < siteList.size() ? siteList.get((nextSiteIdx) + 1) : null;
SiteInfoVO nextSite3 = (nextSiteIdx + 2) < siteList.size() ? siteList.get(nextSiteIdx + 2) : null;
// 上一站
SiteInfoVO preSite = nextSiteIdx - 1 > 0 ? siteList.get(nextSiteIdx - 1) : null;
// 上两站
SiteInfoVO preTwoSite = nextSiteIdx - 2 > 0 ? siteList.get(nextSiteIdx - 2) : null;
// 上三站
SiteInfoVO preThreeSite = nextSiteIdx - 3 > 0 ? siteList.get(nextSiteIdx - 3) : null;
Map<String, String> siteMsgMap;
if (Func.isNotEmpty(preThreeSite)) {
siteMsgMap = new HashMap<>();
siteMsgMap.put("siteName", preThreeSite.getSname());
siteMsgMap.put("type", "before");
snameList.add(siteMsgMap);
}
if (Func.isNotEmpty(preTwoSite)) {
siteMsgMap = new HashMap<>();
siteMsgMap.put("siteName", preTwoSite.getSname());
siteMsgMap.put("type", "before");
snameList.add(siteMsgMap);
}
if (Func.isNotEmpty(preSite)) {
siteMsgMap = new HashMap<>();
siteMsgMap.put("siteName", preSite.getSname());
siteMsgMap.put("type", "before");
snameList.add(siteMsgMap);
}
if (Func.isNotEmpty(nextSite)) {
siteMsgMap = new HashMap<>();
siteMsgMap.put("siteName", nextSite.getSname());
siteMsgMap.put("type", "after");
snameList.add(siteMsgMap);
}
if (Func.isNotEmpty(nextSite2)) {
siteMsgMap = new HashMap<>();
siteMsgMap.put("siteName", nextSite2.getSname());
siteMsgMap.put("type", "after");
snameList.add(siteMsgMap);
}
// if (Func.isNotEmpty(nextSite3)) {
// snameList.add(nextSite3.getSname());
// }
// 计算当前车辆与前一站和后一站的距离
double pass = 0;
if (Func.isNotEmpty(preSite)) {
pass = CommonUtil.calculateDistance(Double.parseDouble(preSite.getJingdu()), Double.parseDouble(preSite.getWeidu()),
Double.parseDouble(info.getJingdu()), Double.parseDouble(info.getWeidu()));
}
double unpass = 0;
if (Func.isNotEmpty(nextSite)) {
unpass = CommonUtil.calculateDistance(Double.parseDouble(nextSite.getJingdu()), Double.parseDouble(nextSite.getWeidu()),
Double.parseDouble(info.getJingdu()), Double.parseDouble(info.getWeidu()));
}
double runPercent = (pass + unpass) > 0 ? (pass / (pass + unpass)) * 100 : 0;
DecimalFormat df1 = new DecimalFormat("#");
// 先从缓存中获取上一次的运行百分比, 然后将本次的运行百分比更新到缓存中
String runPercentStr = df1.format(runPercent > 100 ? 100 : runPercent);
String prePercentStr = (String) redisTemplate.opsForValue().get("car-run-percent-info");
log.error("____________________________________________");
log.error("runPercentStr : " + runPercentStr);
log.error("prePercentStr : " + prePercentStr);
log.error("CarInfoVO: " + info.toString());
prePercentStr = Func.isBlank(prePercentStr) ? "0" : prePercentStr;
redisTemplate.opsForValue().set("car-run-percent-info", runPercentStr, 30, TimeUnit.SECONDS);
Map<String, Object> siteMap = new HashMap<>();
siteMap.put("startSite", siteList.get(0).getSname());
siteMap.put("endSite", siteList.get(siteList.size() - 1).getSname());
siteMap.put("siteList", snameList);
siteMap.put("prePercent", prePercentStr);
siteMap.put("runPercent", runPercentStr);
if (Func.isEmpty(nextSite)) {
nextSite = preSite;
}
BusLine busLine = BusLineCache.getBusLine(info.getUpordown(), nextSite.getSname(), nextSite.getWeizhi());
// 组织返回数据
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("siteData", siteMap);
resultMap.put("catStat", redisTemplate.opsForValue().get("car-current-stat-info" + carNo));
if (Func.isEmpty(busLine)) {
resultMap.put("siteTips", "");
resultMap.put("articleData", "");
resultMap.put("activityData", "");
resultMap.put("scenicData", "");
resultMap.put("imgData", "");
resultMap.put("speed", "");
} else {
resultMap.put("siteTips", busLine.getTips());
resultMap.put("articleData", busLine.getActicle());
resultMap.put("activityData", busLine.getActivity());
resultMap.put("scenicData", busLine.getScenic());
resultMap.put("speed", info.getSpeed());
List<BusLine> busLineList = stationHintService.getBusLineByName(nextSite.getSname());
Long busLineId = busLineList.get(0).getId();
List<imgVo> imgList = proBusLineImgService.getImgByid(busLineId);
redisTemplate.opsForValue().set("imgList-info", imgList);
resultMap.put("imgData", imgList);
}
return R.data(resultMap);
}
}

@ -58,9 +58,9 @@ public class BusLine extends BaseEntity {
private String imgMap;
// 景区图片
private String imgScenic;
//经度
private Double jingdu;
//纬度
private Double weidu;
// //经度
// private Double jingdu;
// //纬度
// private Double weidu;
}

@ -16,8 +16,6 @@
<result column="scenic" property="scenic"/>
<result column="img_map" property="imgMap"/>
<result column="img_scenic" property="imgScenic"/>
<result column="jingdu" property="jingdu"/>
<result column="weidu" property="weidu"/>
</resultMap>
</mapper>

@ -17,11 +17,12 @@ import java.util.List;
public interface IStationHintService extends BaseService<BusLine> {
/**
*查询列表
* @Author chents
* 查询列表
*
* @return
* @Author chents
**/
R QueryStationHint(String linename,String updown);
R QueryStationHint(String linename, String updown);
R<List<StationHintVo>> QueryStationMessage(String linename, String updown);

@ -1,14 +1,19 @@
package org.springblade.modules.business.service.impl;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import org.springblade.common.cache.business.CarInfoCache;
import org.springblade.common.constant.BusinessConstant;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.websocket.service.WebsocketService;
import org.springblade.modules.websocket.vo.WebSocketMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
@ -18,10 +23,6 @@ import java.util.concurrent.TimeUnit;
@Service
public class PublishService {
private static final String CURRENT_FACILITY_STAT = "set-current-Facility-stat";
private static final String CURRENT_FACILITY_RETURN = "return-current-Facility-stat";
@Autowired
private WebsocketService websocketService;
@ -31,11 +32,11 @@ public class PublishService {
/**
* 推送车辆状态数据到web
*
* @Author chents
* @Date 2023/5/10 11:25
* @param carNo
* @param status
* @return
* @Author chents
* @Date 2023/5/10 11:25
**/
public void publishToWeb(String carNo, String status) {
// 1. 启动线程
@ -45,23 +46,25 @@ public class PublishService {
int times = 0;
// 重试策略: 先发三次, 全部失败后, 等待1s再发三次
while (times < 1) {
for (int i=0; i<2; i ++) {
for (int i = 0; i < 2; i++) {
// 2. 调用websocket方法发送数据
String currentFacility = (String) redisTemplate.opsForValue().get(CURRENT_FACILITY_STAT);
Map<String, String> statusMap = new HashMap<>();
statusMap.put("pushCarNo", carNo);
statusMap.put("pushStatus", status);
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("msgType", "status");
dataMap.put("data", statusMap);
WebSocketMessage message = new WebSocketMessage();
message.setTitle(CURRENT_FACILITY_STAT);
message.setTitle("web");
message.setCode(200);
HashMap<String, Object> map = new HashMap<>();
map.put("msgType", CURRENT_FACILITY_STAT);
map.put("data", currentFacility);
String messageJson = JSON.toJSONString(map);
message.setContent(messageJson);
message.setContent(JSON.toJSONString(dataMap));
websocketService.broadcast(message);
// 3. 查看websocket的返回结果
String result = (String) redisTemplate.opsForValue().get(CURRENT_FACILITY_RETURN);
if (Func.isNotBlank(result)) {
//缓存数据到redis,设置5s过期时间
redisTemplate.opsForValue().set(CURRENT_FACILITY_RETURN, carNo + ":" + status, 5, TimeUnit.SECONDS);
String result = (String) redisTemplate.opsForValue().get("websocket-status-return");
if (Func.isNotBlank(result) && BusinessConstant.BOOLEAN_STR_TRUE.equals(result)) {
return;
}
}

@ -31,7 +31,7 @@ import java.util.stream.Collectors;
* @author chents
*/
@Service
public class StationHintServiceImpl extends BaseServiceImpl<BusLineMapper,BusLine> implements IStationHintService {
public class StationHintServiceImpl extends BaseServiceImpl<BusLineMapper, BusLine> implements IStationHintService {
@Resource
BusLineMapper busLineMapper;
@ -44,10 +44,10 @@ public class StationHintServiceImpl extends BaseServiceImpl<BusLineMapper,BusLin
@Override
public R QueryStationHint(String linename,String updown) {
public R QueryStationHint(String linename, String updown) {
QueryWrapper<BusLine> busLineQueryWrapper = new QueryWrapper<>();
busLineQueryWrapper.eq("linename",linename);
busLineQueryWrapper.eq("updown",updown);
busLineQueryWrapper.eq("linename", linename);
busLineQueryWrapper.eq("updown", updown);
busLineQueryWrapper.isNotNull("sname_key");
List<BusLine> busLines = busLineMapper.selectList(busLineQueryWrapper);
List<BusLineVo> busLineVoList = busLines.stream().map(x -> {
@ -56,8 +56,8 @@ public class StationHintServiceImpl extends BaseServiceImpl<BusLineMapper,BusLin
busLineVo.setLinename(x.getLinename());
busLineVo.setUpdown(x.getUpdown());
busLineVo.setSnameKey(x.getSnameKey());
busLineVo.setJingdu(x.getJingdu().toString());
busLineVo.setWeidu(x.getWeidu().toString());
// busLineVo.setJingdu(x.getJingdu().toString());
// busLineVo.setWeidu(x.getWeidu().toString());
return busLineVo;
}).collect(Collectors.toList());
return R.data(busLineVoList);
@ -67,11 +67,11 @@ public class StationHintServiceImpl extends BaseServiceImpl<BusLineMapper,BusLin
@Override
public R<List<StationHintVo>> QueryStationMessage(String linename, String updown) {
QueryWrapper<BusLine> busLineQueryWrapper = new QueryWrapper<>();
busLineQueryWrapper.eq("linename",linename);
busLineQueryWrapper.eq("updown",updown);
busLineQueryWrapper.eq("linename", linename);
busLineQueryWrapper.eq("updown", updown);
busLineQueryWrapper.isNotNull("sname_key");
List<BusLine> busLines = busLineMapper.selectList(busLineQueryWrapper);
if (CollectionUtils.isEmpty(busLines)){
if (CollectionUtils.isEmpty(busLines)) {
throw new ServiceException(StringUtil.format("公交站点信息为空"));
}
List<StationHintVo> stationArr = busLines.stream().map(x -> {
@ -83,11 +83,11 @@ public class StationHintServiceImpl extends BaseServiceImpl<BusLineMapper,BusLin
stationHintVo.setGreen(x.getActivity());
stationHintVo.setYellow(x.getScenic());
QueryWrapper<PocBusLineImg> queryWrapper = new QueryWrapper<>();
queryWrapper.select("img_url","img_type");
queryWrapper.eq("bus_line_id",x.getId());
queryWrapper.select("img_url", "img_type");
queryWrapper.eq("bus_line_id", x.getId());
List<PocBusLineImg> pocBusLineImgs = proBusLineImgMapper.selectList(queryWrapper);
ArrayList<imgVo> imgList = new ArrayList<>();
for(PocBusLineImg pocBusLineImg : pocBusLineImgs){
for (PocBusLineImg pocBusLineImg : pocBusLineImgs) {
imgVo img = new imgVo();
img.setImgUrl(pocBusLineImg.getImgUrl());
img.setImgType(pocBusLineImg.getImgType());
@ -104,11 +104,11 @@ public class StationHintServiceImpl extends BaseServiceImpl<BusLineMapper,BusLin
@Override
public R<List<StationHintVo>> QueryBusLineMessage(String linename, String updown) {
QueryWrapper<BusLine> busLineQueryWrapper = new QueryWrapper<>();
busLineQueryWrapper.eq("linename",linename);
busLineQueryWrapper.eq("updown",updown);
busLineQueryWrapper.eq("linename", linename);
busLineQueryWrapper.eq("updown", updown);
busLineQueryWrapper.isNotNull("sname_key");
List<BusLine> busLines = busLineMapper.selectList(busLineQueryWrapper);
if (CollectionUtils.isEmpty(busLines)){
if (CollectionUtils.isEmpty(busLines)) {
throw new ServiceException(StringUtil.format("公交站点信息为空"));
}
List<StationHintVo> stationArr = busLines.stream().map(x -> {
@ -119,14 +119,12 @@ public class StationHintServiceImpl extends BaseServiceImpl<BusLineMapper,BusLin
stationHintVo.setRed(x.getActicle());
stationHintVo.setGreen(x.getActivity());
stationHintVo.setYellow(x.getScenic());
stationHintVo.setJingdu(x.getJingdu().toString());
stationHintVo.setWeidu(x.getWeidu().toString());
QueryWrapper<PocBusLineImg> queryWrapper = new QueryWrapper<>();
queryWrapper.select("img_url","img_type");
queryWrapper.eq("bus_line_id",x.getId());
queryWrapper.select("img_url", "img_type");
queryWrapper.eq("bus_line_id", x.getId());
List<PocBusLineImg> pocBusLineImgs = proBusLineImgMapper.selectList(queryWrapper);
ArrayList<imgVo> imgList = new ArrayList<>();
for(PocBusLineImg pocBusLineImg : pocBusLineImgs){
for (PocBusLineImg pocBusLineImg : pocBusLineImgs) {
imgVo img = new imgVo();
img.setImgUrl(pocBusLineImg.getImgUrl());
img.setImgType(pocBusLineImg.getImgType());
@ -140,7 +138,7 @@ public class StationHintServiceImpl extends BaseServiceImpl<BusLineMapper,BusLin
}
@Override
public List<BusLine> getBusLineByName(String name) {
public List<BusLine> getBusLineByName(String name) {
QueryWrapper<BusLine> busLineQueryWrapper = new QueryWrapper<>();
busLineQueryWrapper.select("id");
busLineQueryWrapper.eq("sname_key", name);
@ -182,7 +180,7 @@ public class StationHintServiceImpl extends BaseServiceImpl<BusLineMapper,BusLin
private void validateStationHintExists(Long id) {
if (busLineMapper.selectById(id) == null) {
throw new ServiceException(StringUtil.format("当前id为 [{}] 的站点不存在!",id));
throw new ServiceException(StringUtil.format("当前id为 [{}] 的站点不存在!", id));
}
}
}

@ -14,25 +14,25 @@ import java.io.Serializable;
@ToString
public class CarInfoVO implements Serializable {
private static final long serialVersionUID = 1L;
// 车牌号
private String busno;
// 在哪条线路
private String linename;
// 上下行
private String upordown;
// 已经经过了第几个站点
private String inorder;
// 车纬度
private String weidu;
// 车经度
private String jingdu;
// 实时状态 4进站, 5出站, 1运行
private String nowstate;
// 速度
private String speed;
// 车辆上传经纬度的时间
private String gpstime;
private static final long serialVersionUID = 1L;
// 车牌号
private String busno;
// 在哪条线路
private String linename;
// 上下行
private String upordown;
// 已经经过了第几个站点
private String inorder;
// 车纬度
private String weidu;
// 车经度
private String jingdu;
// 实时状态 4进站, 5出站, 1运行
private String nowstate;
// 速度
private String speed;
// 车辆上传经纬度的时间
private String gpstime;
}

@ -1,22 +1,41 @@
package org.springblade.modules.job;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.cache.business.BusLineCache;
import org.springblade.common.cache.business.CarInfoCache;
import org.springblade.common.cache.business.SiteListCache;
import org.springblade.common.constant.BusinessConstant;
import org.springblade.common.utils.CommonUtil;
import org.springblade.common.utils.HttpClientUtils;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.business.entity.BusLine;
import org.springblade.modules.business.service.ICarInfoService;
import org.springblade.modules.business.service.IStationHintService;
import org.springblade.modules.business.vo.CarInfoVO;
import org.springblade.modules.business.vo.SiteInfoVO;
import org.springblade.modules.business.vo.imgVo;
import org.springblade.modules.websocket.service.WebsocketService;
import org.springblade.modules.websocket.vo.WebSocketMessage;
import org.springblade.upload.service.IProBusLineImgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;
import springfox.documentation.spring.web.json.Json;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @Author: Chents
@ -24,95 +43,191 @@ import java.util.Map;
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class CarInfoTask {
private static final String WEB = "web";
private static final String CURRENT_CAR_INFO = "current_car_info";
private static final String PUSH_STATUS = "push_status";
private static final String SPEED = "speed";
@Autowired
private ICarInfoService carInfoService;
private final ICarInfoService carInfoService;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private final RedisTemplate<String, Object> redisTemplate;
@Autowired
private WebsocketService websocketService;
private final WebsocketService websocketService;
@Autowired
private IStationHintService stationHintService;
private final IStationHintService stationHintService;
//@Scheduled(cron = "0/1 * * * * ?")
public void setCarInfo(Map<String, Object> resultMap) {
redisTemplate.opsForValue().set("current_car_info", resultMap);
System.out.println("======存入实时车辆信息到redis成功=========");
}
private final IProBusLineImgService proBusLineImgService;
/**
* 从车辆信息平台同步数据
*/
@Scheduled(cron = "0/1 * * * * ?")
public void syncCarInfo() {
String url = "http://223.99.174.234:9211/BusInfoServer/bus_getstateinfo_1014?userkey=yhlhhh20230323";
String res = HttpClientUtils.doGet(url);
CarInfoCache.setAllCarData(res);
}
@Scheduled(cron = "0/10 * * * * ?")
/**
* 定时将车辆运行信息推送给web
*/
@Scheduled(cron = "0/5 * * * * ?")
public void parseCarInfo() {
//从redis获取数据
Map<String, Object> carInfoMap = (Map<String, Object>) redisTemplate.opsForValue().get("current_car_info");
if (carInfoMap.isEmpty()) {
log.info("======未从redis获取当前车辆实时数据=======");
return;
CarInfoVO info = null;
String allCarData = CarInfoCache.getAllCarData();
JSONObject json = JSON.parseObject(allCarData);
String carNo = CarInfoCache.getPushCarNo();
JSONArray carInfoList = json.getJSONArray("bus");
for (Object o : carInfoList) {
JSONObject carInfo = (JSONObject) o;
if (carNo.equals(carInfo.getString("busno"))) {
info = BeanUtil.copy(carInfo, CarInfoVO.class);
}
}
// 解析车辆信息
HashMap<String, Object> map = new HashMap<>();
map.put("msgType", CURRENT_CAR_INFO);
map.put("data", carInfoMap);
String messageJson = JSON.toJSONString(map);
WebSocketMessage message = new WebSocketMessage();
message.setTitle(WEB);
message.setCode(200);
message.setContent(messageJson);
//log.info("解析车辆信息:{}", carInfoMap.toString());
// 推送消息给web页面
websocketService.broadcast(message);
log.info("推送车辆信息:{}", carInfoMap.toString());
}
List<SiteInfoVO> siteList = SiteListCache.getSiteList(info.getLinename(), info.getUpordown());
int nextSiteIdx = Integer.parseInt(info.getInorder());
if (BusinessConstant.CAR_STAT_IN.toString().equals(info.getNowstate())) {
nextSiteIdx -= 1;
}
@Scheduled(cron = "0/1 * * * * ?")
public void parsePushStatus() {
//从redis获取数据
String carNo = (String) redisTemplate.opsForValue().get("car-current-number");
String pushStatus = (String) redisTemplate.opsForValue().get("set-current-Facility-stat" + carNo);
Map<String, String> resultData = new HashMap<>();
resultData.put("carNo", carNo);
resultData.put("pushStatus", pushStatus);
// 下一站
List<Map<String, String>> snameList = new ArrayList<>();
SiteInfoVO nextSite = nextSiteIdx < siteList.size() ? siteList.get(nextSiteIdx) : null;
SiteInfoVO nextSite2 = (nextSiteIdx + 1) < siteList.size() ? siteList.get((nextSiteIdx) + 1) : null;
SiteInfoVO nextSite3 = (nextSiteIdx + 2) < siteList.size() ? siteList.get(nextSiteIdx + 2) : null;
// 上一站
SiteInfoVO preSite = nextSiteIdx - 1 > 0 ? siteList.get(nextSiteIdx - 1) : null;
// 上两站
SiteInfoVO preTwoSite = nextSiteIdx - 2 > 0 ? siteList.get(nextSiteIdx - 2) : null;
// 上三站
SiteInfoVO preThreeSite = nextSiteIdx - 3 > 0 ? siteList.get(nextSiteIdx - 3) : null;
Map<String, String> siteMsgMap;
if (Func.isNotEmpty(preThreeSite)) {
siteMsgMap = new HashMap<>();
siteMsgMap.put("siteName", preThreeSite.getSname());
siteMsgMap.put("type", "before");
snameList.add(siteMsgMap);
}
if (Func.isNotEmpty(preTwoSite)) {
siteMsgMap = new HashMap<>();
siteMsgMap.put("siteName", preTwoSite.getSname());
siteMsgMap.put("type", "before");
snameList.add(siteMsgMap);
}
if (Func.isNotEmpty(preSite)) {
siteMsgMap = new HashMap<>();
siteMsgMap.put("siteName", preSite.getSname());
siteMsgMap.put("type", "before");
snameList.add(siteMsgMap);
}
if (Func.isNotEmpty(nextSite)) {
siteMsgMap = new HashMap<>();
siteMsgMap.put("siteName", nextSite.getSname());
siteMsgMap.put("type", "after");
snameList.add(siteMsgMap);
}
if (Func.isNotEmpty(nextSite2)) {
siteMsgMap = new HashMap<>();
siteMsgMap.put("siteName", nextSite2.getSname());
siteMsgMap.put("type", "after");
snameList.add(siteMsgMap);
}
// 计算当前车辆与前一站和后一站的距离
double pass = 0;
if (Func.isNotEmpty(preSite)) {
pass = CommonUtil.calculateDistance(Double.parseDouble(preSite.getJingdu()), Double.parseDouble(preSite.getWeidu()),
Double.parseDouble(info.getJingdu()), Double.parseDouble(info.getWeidu()));
}
double unpass = 0;
if (Func.isNotEmpty(nextSite)) {
unpass = CommonUtil.calculateDistance(Double.parseDouble(nextSite.getJingdu()), Double.parseDouble(nextSite.getWeidu()),
Double.parseDouble(info.getJingdu()), Double.parseDouble(info.getWeidu()));
}
double runPercent = (pass + unpass) > 0 ? (pass / (pass + unpass)) * 100 : 0;
DecimalFormat df1 = new DecimalFormat("#");
// 先从缓存中获取上一次的运行百分比, 然后将本次的运行百分比更新到缓存中
String runPercentStr = df1.format(runPercent > 100 ? 100 : runPercent);
String prePercentStr = (String) redisTemplate.opsForValue().get("car-run-percent-info");
prePercentStr = Func.isBlank(prePercentStr) ? "0" : prePercentStr;
redisTemplate.opsForValue().set("car-run-percent-info", runPercentStr, 30, TimeUnit.SECONDS);
Map<String, Object> siteMap = new HashMap<>();
siteMap.put("startSite", siteList.get(0).getSname());
siteMap.put("endSite", siteList.get(siteList.size() - 1).getSname());
siteMap.put("siteList", snameList);
siteMap.put("prePercent", prePercentStr);
siteMap.put("runPercent", runPercentStr);
if (Func.isEmpty(nextSite)) {
nextSite = preSite;
}
BusLine busLine = BusLineCache.getBusLine(info.getUpordown(), nextSite.getSname(), nextSite.getWeizhi());
// 组织返回数据
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("siteData", siteMap);
resultMap.put("catStat", redisTemplate.opsForValue().get("car-current-stat-info" + carNo));
if (Func.isEmpty(busLine)) {
resultMap.put("siteTips", "");
resultMap.put("articleData", "");
resultMap.put("activityData", "");
resultMap.put("scenicData", "");
resultMap.put("imgData", "");
resultMap.put("speed", "");
} else {
resultMap.put("siteTips", busLine.getTips());
resultMap.put("articleData", busLine.getActicle());
resultMap.put("activityData", busLine.getActivity());
resultMap.put("scenicData", busLine.getScenic());
resultMap.put("speed", info.getSpeed());
List<BusLine> busLineList = stationHintService.getBusLineByName(nextSite.getSname());
Long busLineId = busLineList.get(0).getId();
List<imgVo> imgList = proBusLineImgService.getImgByid(busLineId);
resultMap.put("imgData", imgList);
}
// 解析车辆信息
HashMap<String, Object> map = new HashMap<>();
map.put("msgType", PUSH_STATUS);
map.put("data", resultData);
map.put("msgType", CURRENT_CAR_INFO);
map.put("data", resultMap);
String messageJson = JSON.toJSONString(map);
WebSocketMessage message = new WebSocketMessage();
message.setTitle(WEB);
message.setCode(200);
message.setContent(messageJson);
//log.info("解析车辆信息:{}", carInfoMap.toString());
// 推送消息给web页面
websocketService.broadcast(message);
log.info("推送车辆信息:{}", map.toString());
}
@Scheduled(cron = "0/1 * * * * ?")
public void getCarSpeed() {
String carNo = (String) redisTemplate.opsForValue().get("car-current-number");
String carNo = CarInfoCache.getPushCarNo();
CarInfoVO info = carInfoService.getCarInfo(carNo);
if (Func.isEmpty(info)) {
throw new RuntimeException("未获取到车辆信息, 请检查车是否已掉线");
throw new RuntimeException("未获取到车辆信息, 请检查车是否已掉线");
}
String speedJson = JSON.toJSONString(info.getSpeed());
Map<String, String> speedMap = new HashMap<>();
speedMap.put("speed", info.getSpeed());
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("msgType", SPEED);
dataMap.put("data", speedMap);
WebSocketMessage message = new WebSocketMessage();
message.setTitle(WEB);
message.setCode(200);
message.setContent(speedJson);
message.setContent(JSON.toJSONString(dataMap));
websocketService.broadcast(message);
log.info("车辆实时车速:{}", message.getContent());
}
}

@ -21,12 +21,6 @@ import org.springframework.web.bind.annotation.RestController;
public class WebSocketController{
private final WebsocketService websocketService;
// @GetMapping("/broadcast")
// R broadcast(@RequestParam String type, @RequestParam String msg){
// websocketService.broadcast(type, msg);
// return R.status(true);
// }
@GetMapping("/ifhasclient")
boolean ifHasClient(@RequestParam String type){
boolean b = websocketService.ifHasClient(type);

@ -1,13 +1,20 @@
package org.springblade.modules.websocket.handler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import org.springblade.common.constant.BusinessConstant;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.websocket.service.WebsocketService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.concurrent.TimeUnit;
/**
* WebSocketEventListener
*
@ -46,6 +53,8 @@ public class WebsocketHandler extends TextWebSocketHandler {
}
private RedisTemplate redisTemplate;
/**
* 接收客户端推送数据的方法
*
@ -57,7 +66,16 @@ public class WebsocketHandler extends TextWebSocketHandler {
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
System.out.println("Received message from client: " + message.getPayload());
TextMessage msg = new TextMessage(message.getPayload());
session.sendMessage(msg);
}
if (Func.isNotBlank(msg.getPayload())) {
// {"msgType":"status","data":{"status":"ok"}}
JSONObject jsonObject = JSON.parseObject(msg.getPayload());
if ("status".equals(jsonObject.get("msgType"))) {
JSONObject data = jsonObject.getJSONObject("data");
if ("ok".equals(data.get("status"))) {
redisTemplate.opsForValue().set("websocket-status-return", BusinessConstant.BOOLEAN_STR_TRUE, 5, TimeUnit.SECONDS);
}
}
}
}
}

Loading…
Cancel
Save