From 824e3d57b08757a57b0e40059a2ca701450045b3 Mon Sep 17 00:00:00 2001 From: linwl <304115325@qq.com> Date: Mon, 18 Jan 2021 12:19:13 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9D=9Enacos=E5=8C=97=E6=96=97=E8=BE=85?= =?UTF-8?q?=E5=8A=A9=E5=AE=9A=E4=BD=8D=E9=A1=B9=E7=9B=AE=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 2 + .idea/BeidouAstPos.iml | 9 + .idea/google-java-format.xml | 6 + .idea/inspectionProfiles/Project_Default.xml | 36 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + pom.xml | 148 ++++ setup_dev.sh | 64 ++ .../telpo/beidouast/BaidouAstApplication.java | 53 ++ .../beidouast/annotation/MongoSwitch.java | 22 + .../beidouast/co/PositionConfigInfo.java | 35 + .../com/telpo/beidouast/common/CSVUtil.java | 87 +++ .../telpo/beidouast/common/HexConvert.java | 140 ++++ .../telpo/beidouast/common/OkHttpUtil.java | 154 ++++ .../com/telpo/beidouast/common/RedisUtil.java | 665 ++++++++++++++++++ .../telpo/beidouast/common/SocketClient.java | 98 +++ .../beidouast/config/AsyncExecutorConfig.java | 69 ++ .../telpo/beidouast/config/OkHttpConfig.java | 99 +++ .../beidouast/config/PositionConfig.java | 61 ++ .../config/SchedulingExecutorConfig.java | 53 ++ .../beidouast/config/db/MongoDbContext.java | 65 ++ .../config/db/MongoListProperties.java | 30 + .../config/db/MultiMongoTemplate.java | 26 + .../controller/DipperPositionController.java | 26 + .../entity/mongo/IPProvinceEntity.java | 24 + .../beidouast/enums/DipperReturnValue.java | 53 ++ .../beidouast/handler/NettyServerHandler.java | 181 +++++ .../handler/ServerChannelInitializer.java | 24 + .../beidouast/mapper/IPProvinceMapper.java | 58 ++ .../server/DipperPositionServer.java | 257 +++++++ .../IDipperAstPosAsyncTaskService.java | 27 + .../IDipperAstTimeAsyncTaskService.java | 17 + .../service/IDipperDataAsyncTaskService.java | 28 + .../beidouast/service/IPProvinceService.java | 45 ++ .../DipperAstPosAsyncTaskServiceImpl.java | 247 +++++++ .../DipperAstTimeAsyncTaskServiceImpl.java | 106 +++ .../impl/DipperDataAsyncTaskServiceImpl.java | 68 ++ .../service/impl/IPProvinceServiceImpl.java | 62 ++ .../telpo/beidouast/task/ScheduleService.java | 40 ++ .../com/telpo/beidouast/vo/IPProvinceVo.java | 20 + src/main/resources/bootstrap.yaml | 69 ++ src/main/resources/csv/provinceLonAlt.csv | 35 + src/main/resources/log/logback-spring.xml | 198 ++++++ 44 files changed, 3527 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/BeidouAstPos.iml create mode 100644 .idea/google-java-format.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 pom.xml create mode 100644 setup_dev.sh create mode 100644 src/main/java/com/telpo/beidouast/BaidouAstApplication.java create mode 100644 src/main/java/com/telpo/beidouast/annotation/MongoSwitch.java create mode 100644 src/main/java/com/telpo/beidouast/co/PositionConfigInfo.java create mode 100644 src/main/java/com/telpo/beidouast/common/CSVUtil.java create mode 100644 src/main/java/com/telpo/beidouast/common/HexConvert.java create mode 100644 src/main/java/com/telpo/beidouast/common/OkHttpUtil.java create mode 100644 src/main/java/com/telpo/beidouast/common/RedisUtil.java create mode 100644 src/main/java/com/telpo/beidouast/common/SocketClient.java create mode 100644 src/main/java/com/telpo/beidouast/config/AsyncExecutorConfig.java create mode 100644 src/main/java/com/telpo/beidouast/config/OkHttpConfig.java create mode 100644 src/main/java/com/telpo/beidouast/config/PositionConfig.java create mode 100644 src/main/java/com/telpo/beidouast/config/SchedulingExecutorConfig.java create mode 100644 src/main/java/com/telpo/beidouast/config/db/MongoDbContext.java create mode 100644 src/main/java/com/telpo/beidouast/config/db/MongoListProperties.java create mode 100644 src/main/java/com/telpo/beidouast/config/db/MultiMongoTemplate.java create mode 100644 src/main/java/com/telpo/beidouast/controller/DipperPositionController.java create mode 100644 src/main/java/com/telpo/beidouast/entity/mongo/IPProvinceEntity.java create mode 100644 src/main/java/com/telpo/beidouast/enums/DipperReturnValue.java create mode 100644 src/main/java/com/telpo/beidouast/handler/NettyServerHandler.java create mode 100644 src/main/java/com/telpo/beidouast/handler/ServerChannelInitializer.java create mode 100644 src/main/java/com/telpo/beidouast/mapper/IPProvinceMapper.java create mode 100644 src/main/java/com/telpo/beidouast/server/DipperPositionServer.java create mode 100644 src/main/java/com/telpo/beidouast/service/IDipperAstPosAsyncTaskService.java create mode 100644 src/main/java/com/telpo/beidouast/service/IDipperAstTimeAsyncTaskService.java create mode 100644 src/main/java/com/telpo/beidouast/service/IDipperDataAsyncTaskService.java create mode 100644 src/main/java/com/telpo/beidouast/service/IPProvinceService.java create mode 100644 src/main/java/com/telpo/beidouast/service/impl/DipperAstPosAsyncTaskServiceImpl.java create mode 100644 src/main/java/com/telpo/beidouast/service/impl/DipperAstTimeAsyncTaskServiceImpl.java create mode 100644 src/main/java/com/telpo/beidouast/service/impl/DipperDataAsyncTaskServiceImpl.java create mode 100644 src/main/java/com/telpo/beidouast/service/impl/IPProvinceServiceImpl.java create mode 100644 src/main/java/com/telpo/beidouast/task/ScheduleService.java create mode 100644 src/main/java/com/telpo/beidouast/vo/IPProvinceVo.java create mode 100644 src/main/resources/bootstrap.yaml create mode 100644 src/main/resources/csv/provinceLonAlt.csv create mode 100644 src/main/resources/log/logback-spring.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..e7e9d11 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml diff --git a/.idea/BeidouAstPos.iml b/.idea/BeidouAstPos.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/BeidouAstPos.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/google-java-format.xml b/.idea/google-java-format.xml new file mode 100644 index 0000000..2aa056d --- /dev/null +++ b/.idea/google-java-format.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..6560a98 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,36 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..28a804d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..d56d93b --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..3dd8917 --- /dev/null +++ b/pom.xml @@ -0,0 +1,148 @@ + + + 4.0.0 + com.telpo + beidouast + 1.0-SNAPSHOT + beidouast + 北斗定位服务 + jar + + + org.springframework.boot + spring-boot-starter-parent + 2.2.5.RELEASE + + + + UTF-8 + UTF-8 + 1.8 + UTF-8 + 2.2.0.RELEASE + Hoxton.RELEASE + true + + + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + + org.projectlombok + lombok + true + + + + + com.telpo + common + 1.1.19 + + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + org.apache.commons + commons-lang3 + 3.10 + + + + + org.yaml + snakeyaml + 1.25 + + + + com.alibaba + fastjson + 1.2.28 + + + + io.netty + netty-all + 4.1.13.Final + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + org.apache.commons + commons-pool2 + + + + + com.squareup.okhttp3 + okhttp + 4.8.0 + + + + + de.codecentric + spring-boot-admin-starter-client + 2.2.4 + + + + + net.sourceforge.javacsv + javacsv + 2.0 + + + + com.mongodb + mongo + 1.0 + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + true + + + + + repackage + + + + + + + \ No newline at end of file diff --git a/setup_dev.sh b/setup_dev.sh new file mode 100644 index 0000000..bf815d6 --- /dev/null +++ b/setup_dev.sh @@ -0,0 +1,64 @@ +#!/bin/bash +mvn clean +mvn package -Dmaven.test.skip=true +#image_version=$(date +%Y%m%d%H%M) +image_version=$version + +docker cp docker_jenkins:/var/jenkins_home/workspace/beidou_ast/target/beidouast.jar /usr/local/beidou_ast/beidou_ast.jar +#docker stop dipperposition_service || true +#docker rm dipperposition_service || true + +# 删除镜像 +#docker rmi -f $(docker images | grep telpo/dipperposition_service | awk '{print $3}') + +#docker build . -t telpo/dipperposition_service:$image_version + +#TODO:推送镜像到私有仓库 +#echo '=================开始推送镜像=======================' +#docker tag telpo/dipperposition_service:$image_version 139.224.254.18:5000/dipperposition_service:$image_version +#docker push 139.224.254.18:5000/dipperposition_service:$image_version +#echo '=================推送镜像完成=======================' + +#删除产生的None镜像 +#docker rmi -f $(docker images | grep none | awk '{print $3}') +# 查看镜像列表 +#docker images +# 启动容器 +#docker run -v /home/data/dipperposition/log:/var/log/dipperposition -d -e active=dev --network host --restart=always +# -p 9011:9011 -p 9012:9012 -p 9013:9013 --name dipperposition_service 139.224.254.18:5000/dipperposition_service:$image_version + +#echo "scp ${WORKSPACE} files......begin" +#set passwd "telpo#1234" +#scp /var/jenkins_home/workspace/dipperpos_service/target/dipperposition.jar root@47.116.142.20:/home/data/dipperposition/dipperposition.jar +#expect { +# "密码:" +# { +# send "$passwd\n" +# } +# "pass" +# { +# send "$passwd\n" +# } +# +# "yes/no" +# { +# sleep 5 +# send_user "send yes" +# send "yes\n" +# } +# eof +# { +# sleep 5 +# send_user "eof\n" +# } +#} +#send "exit\r" +#expect eof +#echo "scp ${WORKSPACE} files......end" +# 查看日志 +# docker logs dipperposition_service + +echo '=================启动NettyAPP=======================' +ps -ef |grep beidou |awk '{print $2}'|xargs kill -9 +java -jar -Xms256m -Xmx256m -Xss256k -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m /usr/local/beidou_ast/beidouast.jar +echo '=================完成NettyAPP启动=======================' diff --git a/src/main/java/com/telpo/beidouast/BaidouAstApplication.java b/src/main/java/com/telpo/beidouast/BaidouAstApplication.java new file mode 100644 index 0000000..5bd0286 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/BaidouAstApplication.java @@ -0,0 +1,53 @@ +package com.telpo.dipperposition; + +import com.alibaba.nacos.api.NacosFactory; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.config.listener.Listener; +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.exception.NacosException; +import com.telpo.dipperposition.co.PositionConfigInfo; +import com.telpo.dipperposition.server.DipperPositionServer; +import com.telpo.dipperposition.server.EphAsyncServer; +import com.telpo.dipperposition.server.TimeAsyncServer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +import java.util.Properties; +import java.util.concurrent.Executor; + +/** + * @program: gateway + * @description: 网关启动类 + * @author: linwl + * @create: 2020-06-18 16:39 + */ +@SpringBootApplication +@EnableDiscoveryClient +@ConfigurationPropertiesScan +@EnableAsync +@EnableScheduling +@Slf4j +public class BaidouAstApplication { + + public static void main(String[] args) { + try { + log.info("北斗定位服务开始!"); + ConfigurableApplicationContext applicationContext = SpringApplication.run(BaidouAstApplication.class, args); + log.info("北斗定位服务启动!"); + //启动服务端 + ConfigurableEnvironment environment = applicationContext.getEnvironment(); + DipperPositionServer nettyServer = new DipperPositionServer(environment); + nettyServer.start2(); + } catch (Exception e) { + log.error(e.getMessage()); + } + } +} diff --git a/src/main/java/com/telpo/beidouast/annotation/MongoSwitch.java b/src/main/java/com/telpo/beidouast/annotation/MongoSwitch.java new file mode 100644 index 0000000..6153006 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/annotation/MongoSwitch.java @@ -0,0 +1,22 @@ +package com.telpo.dipperposition.annotation; + +import java.lang.annotation.*; + +/** + * @program: DataPushServer + * @description: mongo数据源切换注解 + * @author: linwl + * @create: 2020-07-11 15:06 + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface MongoSwitch { + + /** + * mongo数据库名称 + * + * @return + */ + String value() default ""; +} diff --git a/src/main/java/com/telpo/beidouast/co/PositionConfigInfo.java b/src/main/java/com/telpo/beidouast/co/PositionConfigInfo.java new file mode 100644 index 0000000..47c2d16 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/co/PositionConfigInfo.java @@ -0,0 +1,35 @@ +package com.telpo.dipperposition.co; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import okhttp3.*; +import okhttp3.internal.ws.RealWebSocket; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import javax.net.SocketFactory; + +/** + * @program: RzlAccount + * @description: 融智联账号配置 + * @author: king + * @create: 2021-01-12 14:02 + **/ +@Getter +@Setter +@Component +@ConfigurationProperties(prefix = "position-server") +public class PositionConfigInfo { + + private String serverAddr; + + private String timeAsycPort; + + private String posAsycPort; + + private String starsAsycPort; + +} diff --git a/src/main/java/com/telpo/beidouast/common/CSVUtil.java b/src/main/java/com/telpo/beidouast/common/CSVUtil.java new file mode 100644 index 0000000..e6d1ab0 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/common/CSVUtil.java @@ -0,0 +1,87 @@ +package com.telpo.dipperposition.common; + +import com.csvreader.CsvReader; +import com.csvreader.CsvWriter; + +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +/** + * @program: dipperposition + * @description: CSV文件读取单元 + * @author: linwl + * @create: 2021-01-14 11:19 + **/ +public class CSVUtil { + /** + * 读取每行的数据 + * + * @param readPath + * @return + */ + public static List readCSV(String readPath) { + String filePath = readPath; + List listData = new ArrayList<>(); + try { + filePath = readPath; + CsvReader csvReader = new CsvReader(filePath); + // 读表头 + boolean re = csvReader.readHeaders(); + while (csvReader.readRecord()) { + String rawRecord = csvReader.getRawRecord(); + listData.add(rawRecord); + } + return listData; + } catch (FileNotFoundException e) { + throw new RuntimeException("文件未找到"); + } catch (IOException e) { + throw new RuntimeException(e.getMessage()); + } + + } + + /** + * 写入文件头 + * @param writePath + * @param header + */ + public static void writeCSV(String writePath, String[] header) { + String filePath = writePath; + try { + CsvWriter csvWriter = new CsvWriter(writePath, ',', Charset.forName("UTF-8")); + //String [] header = {"SkuId","SsuId","图片地址","大小(bit)","高度","宽度"}; + csvWriter.writeRecord(header); + csvWriter.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + /** + * 利用输入输出流持续写 + * @param fileName + * @param content + */ + public static void writeContent(String fileName, String content) { + FileWriter writer = null; + try { + // 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件 + writer = new FileWriter(fileName, true); + writer.write(content + "\r\n"); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (writer != null) { + writer.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/com/telpo/beidouast/common/HexConvert.java b/src/main/java/com/telpo/beidouast/common/HexConvert.java new file mode 100644 index 0000000..8f79122 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/common/HexConvert.java @@ -0,0 +1,140 @@ +package com.telpo.dipperposition.common; + +/** + * @program: dipperposition + * @description: 16进制处理 + * @author: linwl + * @create: 2021-01-14 22:05 + **/ +public class HexConvert { + public static String convertStringToHex(String str){ + + char[] chars = str.toCharArray(); + + StringBuffer hex = new StringBuffer(); + for(int i = 0; i < chars.length; i++){ + hex.append(Integer.toHexString((int)chars[i])); + } + + return hex.toString(); + } + + public static String convertHexToString(String hex){ + + StringBuilder sb = new StringBuilder(); + StringBuilder sb2 = new StringBuilder(); + + for( int i=0; i> 4)); + hex += String.valueOf(hexStr.charAt(b & 0x0F)); + result += hex + " "; + } + return result; + } + + //將10進制轉換為16進制 + public static String encodeHEX(long numb){ + + String hex= Long.toHexString(numb); + return hex; + + } + + + //將16進制字符串轉換為10進制數字 + public static long decodeHEX(String hexs){ + long longValue= Long.parseLong("123ABC", 16); + return longValue; + } + + + /** + * 生成校验码的int值 + * */ + public static String makeChecksum(String data) { + if (data == null || data.equals("")) { + return ""; + } + int total = 0; + int len = data.length(); + int num = 0; + while (num < len) { + String s = data.substring(num, num + 2); + //System.out.println(s); + total += Integer.parseInt(s, 16); + num = num + 2; + } + /** + * 用256求余最大是255,即16进制的FF + */ + int mod = total % 256; + String hex = Integer.toHexString(mod); + len = hex.length(); + // 如果不够校验位的长度,补0,这里用的是两位校验 + if (len < 2) { + hex = "0" + hex; + } + return hex; + } +// +// public static void main(String[] args) { +// +// +// System.out.println("======ASCII码转换为16进制======"); +// String str = "*00007VERSION\\n1$"; +// System.out.println("字符串: " + str); +// String hex = HexConvert.convertStringToHex(str); +// System.out.println("====转换为16进制=====" + hex); +// +// System.out.println("======16进制转换为ASCII======"); +// System.out.println("Hex : " + hex); +// System.out.println("ASCII : " + HexConvert.convertHexToString(hex)); +// +// byte[] bytes = HexConvert.hexStringToBytes( hex ); +// +// System.out.println(HexConvert.BinaryToHexString( bytes )); +// } + +} diff --git a/src/main/java/com/telpo/beidouast/common/OkHttpUtil.java b/src/main/java/com/telpo/beidouast/common/OkHttpUtil.java new file mode 100644 index 0000000..44b01cc --- /dev/null +++ b/src/main/java/com/telpo/beidouast/common/OkHttpUtil.java @@ -0,0 +1,154 @@ +package com.telpo.dipperposition.common; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import okhttp3.*; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.text.MessageFormat; +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; + +/** + * @program: DataPushServer + * @description: okhttp工具类 + * @author: linwl + * @create: 2020-07-17 15:43 + */ +@Slf4j +@Component +public class OkHttpUtil { + + @Autowired private OkHttpClient okHttpClient; + + /** + * 根据map获取get请求参数 + * + * @param queries + * @return + */ + public StringBuffer getQueryString(String url, Map queries) { + StringBuffer sb = new StringBuffer(url); + if (queries != null && queries.keySet().size() > 0) { + boolean firstFlag = true; + Iterator iterator = queries.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = (Map.Entry) iterator.next(); + if (firstFlag) { + sb.append("?" + entry.getKey() + "=" + entry.getValue()); + firstFlag = false; + } else { + sb.append("&" + entry.getKey() + "=" + entry.getValue()); + } + } + } + return sb; + } + + /** + * get + * + * @param url 请求的url + * @param queries 请求的参数,在浏览器?后面的数据,没有可以传null + * @return + */ + public String get(String url, Map queries) { + StringBuffer sb = getQueryString(url, queries); + Request request = new Request.Builder().url(sb.toString()).build(); + log.debug(MessageFormat.format("发送Get to url<{0}>,参数为:{1}", url, queries)); + return execNewCall(request); + } + + /** + * post + * + * @param url 请求的url + * @param params post form 提交的参数 + * @return + */ + public String postFormParams(String url, Map params) { + FormBody.Builder builder = new FormBody.Builder(); + // 添加参数 + if (params != null && params.keySet().size() > 0) { + for (String key : params.keySet()) { + builder.add(key, params.get(key)); + } + } + log.debug(MessageFormat.format("发送post from to url<{0}>,参数为:{1}", url, params)); + Request request = new Request.Builder().url(url).post(builder.build()).build(); + return execNewCall(request); + } + + /** Post请求发送JSON数据....{"name":"zhangsan","pwd":"123456"} 参数一:请求Url 参数二:请求的JSON 参数三:请求回调 */ + public String postJsonParams(String url, String jsonParams) { + RequestBody requestBody = RequestBody.create(jsonParams, MediaType.parse("application/json; charset=utf-8")); + Request request = new Request.Builder().url(url).post(requestBody).build(); + log.debug(MessageFormat.format("发送post json to url<{0}>,参数为:{1}", url, jsonParams)); + return execNewCall(request); + } + + /** Post请求发送xml数据.... 参数一:请求Url 参数二:请求的xmlString 参数三:请求回调 */ + public String postXmlParams(String url, String xml) { + RequestBody requestBody = + RequestBody.create(xml, MediaType.parse("application/xml; charset=utf-8")); + Request request = new Request.Builder().url(url).post(requestBody).build(); + log.debug(MessageFormat.format("发送post xml to url<{0}>,参数为:{1}", url, xml)); + return execNewCall(request); + } + + /** + * 调用okhttp的newCall方法 + * + * @param request + * @return + */ + private String execNewCall(Request request) { + try (Response response = okHttpClient.newCall(request).execute()) { + if (response.isSuccessful()) { + return Objects.requireNonNull(response.body()).string(); + } + } catch (Exception e) { + log.error("okhttp3 put error >> ex = {}", ExceptionUtils.getStackTrace(e)); + } + return "FAIL"; + } + + /** + * Post请求发送JSON数据....{"name":"zhangsan","pwd":"123456"} 参数一:请求Url 参数二:请求的JSON 参数三:请求回调 + */ + public String postJsonParamsWithToken(String url, String token, String jsonParams) { + RequestBody requestBody = + RequestBody.create(jsonParams, MediaType.parse("application/json; charset=utf-8")); + Request request = new Request.Builder().url(url). + addHeader("Authorization", token).post(requestBody).build(); + log.debug(MessageFormat.format("发送post json to url<{0}>,参数为:{1}", url, jsonParams)); + return execNewCall(request); + } + + public JSONObject postRequestWithJson(String url, String accessToken, JSONObject postData) { + String postResult; + if (ObjectUtils.isNotEmpty(accessToken)) { + postResult = postJsonParamsWithToken(url, accessToken, JSONObject.toJSONString(postData)); + } else { + postResult = postJsonParams(url, JSONObject.toJSONString(postData)); + } + + if (postResult == null) { + log.error("访问错误"); + return null; + } else { + log.debug(postResult); + if(("FAIL").equals(postResult.toString())) { + JSONObject object = new JSONObject(); + object.put("result", "FAIL"); + return object; + } else { + return JSONObject.parseObject(postResult); + } + } + } +} diff --git a/src/main/java/com/telpo/beidouast/common/RedisUtil.java b/src/main/java/com/telpo/beidouast/common/RedisUtil.java new file mode 100644 index 0000000..97933f0 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/common/RedisUtil.java @@ -0,0 +1,665 @@ +package com.telpo.dipperposition.common; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * @program: DataPushServer + * @description: redis工具类 + * @author: linwl + * @create: 2020-07-11 10:26 + */ +@Component +@Slf4j +public class RedisUtil { + + @Resource private RedisTemplate redisTemplate; + + // =============================common============================ + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @return + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 根据key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public void del(String... key) { + if (key != null && key.length > 0) { + if (key.length == 1) { + redisTemplate.delete(key[0]); + } else { + redisTemplate.delete(CollectionUtils.arrayToList(key)); + } + } + } + + // ============================String============================= + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 递增 适用场景: https://blog.csdn.net/y_y_y_k_k_k_k/article/details/79218254 高并发生成订单号,秒杀类的业务逻辑等。。 + * + * @param key 键 + * @param delta 要增加几(大于0) + * @return + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, delta); + } + + /** + * 递减 + * + * @param key 键 + * @param delta 要减少几(小于0) + * @return + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, -delta); + } + + // ================================Map================================= + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisTemplate.opsForHash().entries(key); + } + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + + // ============================set============================= + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + log.error(key, e); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + log.error(key, e); + return 0; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + log.error(key, e); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + log.error(key, e); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + log.error(key, e); + return 0; + } + } + + // ============================zset============================= + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set zSGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + log.error(key, e); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean zSHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + public Boolean zSSet(String key, Object value, double score) { + try { + return redisTemplate.opsForZSet().add(key, value, 2); + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long zSSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + log.error(key, e); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long zSGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + log.error(key, e); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long zSetRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + log.error(key, e); + return 0; + } + } + // ===============================list================================= + + /** + * 获取list缓存的内容 取出来的元素 总数 end-start+1 + * + * @param key 键 + * @param start 开始 0 是第一个元素 + * @param end 结束 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + log.error(key, e); + return null; + } + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + log.error(key, e); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + log.error(key, e); + return null; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, List value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + log.error(key, e); + return false; + } + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + Long remove = redisTemplate.opsForList().remove(key, count, value); + return remove; + } catch (Exception e) { + log.error(key, e); + return 0; + } + } +} diff --git a/src/main/java/com/telpo/beidouast/common/SocketClient.java b/src/main/java/com/telpo/beidouast/common/SocketClient.java new file mode 100644 index 0000000..b017c6a --- /dev/null +++ b/src/main/java/com/telpo/beidouast/common/SocketClient.java @@ -0,0 +1,98 @@ +package com.telpo.dipperposition.common; + +import lombok.extern.slf4j.Slf4j; + +import java.io.*; +import java.net.Socket; +import java.nio.charset.StandardCharsets; + +/** + * @program: dipperposition + * @description: socket连接单元 + * @author: king + * @create: 2021-01-14 13:52 + **/ +@Slf4j +public class SocketClient { + //定义一个Socket对象 + Socket socket = null; + + public SocketClient(String host, int port, int timeout) { + try { + //需要服务器的IP地址和端口号,才能获得正确的Socket对象 + socket = new Socket(host, port); + socket.setSoTimeout(timeout); + } catch (IOException e) { + log.error("Socket Connect Error:" + e.getMessage()); + } + } + + public String getOutput() { + try { + OutputStream os = socket.getOutputStream(); + return os.toString(); + } catch (IOException e) { + log.error("Socket getOutputStream Error:" + e.getMessage()); + return null; + } + } + + + public String sendCmd(String astCmd, String ackAckCheckRef) { + try { + OutputStream os=socket.getOutputStream(); + PrintWriter pw=new PrintWriter(os); + // TODO 发生命令 + //String info="用户名:Tom,用户密码:123456"; + pw.write(astCmd); + pw.flush(); + socket.shutdownOutput(); + + //接收服务器的相应 + String reply=null; + //输入流 + InputStream is=socket.getInputStream(); + //BufferedReader br=new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + + //StringBuffer ackResultBuf= new StringBuffer(); + //String ackHexOut = HexConvert.convertStringToHex(ackAckCheckRef); +// reply=br.readLine(); +// while(reply!=null){ +// //log.debug("接收服务器的信息:"+reply); +// //if (ackHexOut.equals(reply)) { +// ackResultBuf.append(reply); +// reply=br.readLine(); +// // break; +// //} +// } + int rc = 0; + while ((rc = is.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + byte[] in2b = swapStream.toByteArray(); + //String ackResult = HexConvert.convertHexToString(ackResultBuf.toString()); + //4.关闭资源 + swapStream.close(); + is.close(); + pw.close(); + os.close(); + //log.debug(ackResult); + log.debug("接收服务器的信息:"+HexConvert.BinaryToHexString(in2b)); + return HexConvert.BinaryToHexString(in2b); + } catch (IOException e) { + log.error("Socket sendCmd Error:" + e.getMessage()); + return null; + } + } + + public void closeConnection() { + try { + socket.close(); + //socket.shutdownOutput(); + } catch (IOException e) { + log.error("Socket getOutputStream Error:" + e.getMessage()); + } + } +} diff --git a/src/main/java/com/telpo/beidouast/config/AsyncExecutorConfig.java b/src/main/java/com/telpo/beidouast/config/AsyncExecutorConfig.java new file mode 100644 index 0000000..a339326 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/config/AsyncExecutorConfig.java @@ -0,0 +1,69 @@ +package com.telpo.dipperposition.config; + +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * @program: DataPushServer + * @description: + * @author: linwl + * @create: 2020-07-11 09:17 + */ +@Configuration +@Slf4j +public class AsyncExecutorConfig implements AsyncConfigurer { + + @Value("${async.pool.corePoolSize}") + private int corePoolSize; + + @Value("${async.pool.maxPoolSize}") + private int maxPoolSize; + + @Value("${async.pool.queueCapacity}") + private int queueCapacity; + + @Bean(name = "asyncServiceExecutor") + public Executor asyncServiceExecutor() { + log.info("start asyncServiceExecutor"); + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + // 配置核心线程数 + executor.setCorePoolSize(corePoolSize); + // 配置最大线程数 + executor.setMaxPoolSize(maxPoolSize); + // 配置队列大小 + executor.setQueueCapacity(queueCapacity); + // 配置线程池中的线程的名称前缀 + String threadNamePrefix = "async-pool-"; + executor.setThreadNamePrefix(threadNamePrefix); + + // 设置拒绝策略:当pool已经达到max size的时候,如何处理新任务 + // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + // 执行初始化 + executor.initialize(); + return executor; + } + + /** + * 异步任务中异常处理 + * + * @return + */ + @Override + public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { + return (arg0, arg1, arg2) -> { + log.error("==========================" + arg0.getMessage() + "=======================", arg0); + log.error("com.telpo.auth.exception method:" + arg1.getName()); + }; + } +} diff --git a/src/main/java/com/telpo/beidouast/config/OkHttpConfig.java b/src/main/java/com/telpo/beidouast/config/OkHttpConfig.java new file mode 100644 index 0000000..6fd53c8 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/config/OkHttpConfig.java @@ -0,0 +1,99 @@ +package com.telpo.dipperposition.config; + +import lombok.extern.slf4j.Slf4j; +import okhttp3.ConnectionPool; +import okhttp3.OkHttpClient; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.concurrent.TimeUnit; + +/** + * @program: DataPushServer + * @description: http设置 + * @author: linwl + * @create: 2020-07-17 15:29 + */ +@Configuration +@Slf4j +public class OkHttpConfig { + + @Value("${OkHttp-config.pool.max-conn}") + private Integer maxConn; + + @Value("${OkHttp-config.pool.keep-alive}") + private Integer keepAlive; + + @Value("${OkHttp-config.read-timeout}") + private long readTimeout; + + @Value("${OkHttp-config.conn-timeout}") + private long connTimeout; + + @Value("${OkHttp-config.write-timeout}") + private long writeTimeout; + + @Bean + public X509TrustManager x509TrustManager() { + return new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] x509Certificates, String s) + throws CertificateException {} + + @Override + public void checkServerTrusted(X509Certificate[] x509Certificates, String s) + throws CertificateException {} + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + }; + } + + @Bean + public SSLSocketFactory sslSocketFactory() { + try { + // 信任任何链接 + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, new TrustManager[] {x509TrustManager()}, new SecureRandom()); + return sslContext.getSocketFactory(); + } catch (NoSuchAlgorithmException | KeyManagementException e) { + log.error("okhttp3 send https error:", e); + } + return null; + } + + /** + * Create a new connection pool with tuning parameters appropriate for a single-user application. + * The tuning parameters in this pool are subject to change in future OkHttp releases. Currently + */ + @Bean + public ConnectionPool pool() { + return new ConnectionPool(maxConn, keepAlive, TimeUnit.MINUTES); + } + + @Bean + public OkHttpClient okHttpClient() { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder + .connectTimeout(connTimeout, TimeUnit.SECONDS) + .readTimeout(readTimeout, TimeUnit.SECONDS) + .writeTimeout(writeTimeout, TimeUnit.SECONDS) + .connectionPool(pool()) // 连接池 + .retryOnConnectionFailure(true) + .hostnameVerifier((s, sslSession) -> true) + .sslSocketFactory(sslSocketFactory(), x509TrustManager()); + return builder.build(); + } +} diff --git a/src/main/java/com/telpo/beidouast/config/PositionConfig.java b/src/main/java/com/telpo/beidouast/config/PositionConfig.java new file mode 100644 index 0000000..6e7d36e --- /dev/null +++ b/src/main/java/com/telpo/beidouast/config/PositionConfig.java @@ -0,0 +1,61 @@ +package com.telpo.dipperposition.config; + +import com.telpo.dipperposition.co.PositionConfigInfo; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import okhttp3.OkHttpClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @program: gateway + * @description: jwt设置 + * @author: linwl + * @create: 2020-06-18 17:45 + */ +@Getter +@Setter +@Configuration +public class PositionConfig { + + //@Autowired + //private ConfigurableApplicationContext configurableApplicationContext; + //@Value(value = "${position.hello}") + //private String hello; + + //@Value(value = "${spring.application.name}") + //private String name; + +// @Value(value = "${position.server.serverAddr}") +// private String serverAddr; +// +// @Value(value = "${position.server.timeAsycPort}") +// private String timeAsycServerPort; +// +// @Value(value = "${position.server.posAsycPort}") +// private String posAsycServerPort; +// +// @Value(value = "${position.server.starsAsycPort}") +// private String starsAsycServerPort; + + PositionConfig() + { + //hello = configurableApplicationContext.getEnvironment().getProperty("position.hello"); + //name = configurableApplicationContext.getEnvironment().getProperty("spring.application.name"); + } +// +// @Bean (name = "positionConfigInfo") +// public PositionConfigInfo positionConfigInfo(){ +// PositionConfigInfo configInfo = new PositionConfigInfo(); +// configInfo.setServerAddr(this.serverAddr); +// configInfo.setTimeAsycServerPort(this.timeAsycServerPort); +// configInfo.setPosAsycServerPort(this.posAsycServerPort); +// configInfo.setStarsAsycServerPort(this.starsAsycServerPort); +// System.out.print(configInfo.toString()); +// return configInfo; +// } +} diff --git a/src/main/java/com/telpo/beidouast/config/SchedulingExecutorConfig.java b/src/main/java/com/telpo/beidouast/config/SchedulingExecutorConfig.java new file mode 100644 index 0000000..2bfd302 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/config/SchedulingExecutorConfig.java @@ -0,0 +1,53 @@ +package com.telpo.dipperposition.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.SchedulingConfigurer; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; + +/** + * @program: DataPushServer + * @description: 定时任务线程配置 + * @author: linwl + * @create: 2020-07-24 10:53 + */ +@Getter +@Setter +@Configuration +public class SchedulingExecutorConfig implements SchedulingConfigurer { + + @Value("${scheduler.pool.size}") + private int pollSize; + + @Value("${scheduler.pool.await-seconds}") + private int awaitSeconds; + + @Value("${pos.ast.server}") + private String astServer; + @Value("${pos.ast.ephAstPort}") + private int ephAstPort; + @Value("${pos.ast.ephAstHexPort}") + private int ephAstHexPort; + @Value("${pos.ast.timeout}") + private int astTimeout; + + @Override + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + ThreadPoolTaskScheduler taskScheduler = taskScheduler(); + taskRegistrar.setTaskScheduler(taskScheduler); + } + + @Bean(destroyMethod = "shutdown", name = "taskScheduler") + public ThreadPoolTaskScheduler taskScheduler() { + ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); + scheduler.setPoolSize(pollSize); + scheduler.setThreadNamePrefix("task-"); + scheduler.setAwaitTerminationSeconds(awaitSeconds); + scheduler.setWaitForTasksToCompleteOnShutdown(true); + return scheduler; + } +} diff --git a/src/main/java/com/telpo/beidouast/config/db/MongoDbContext.java b/src/main/java/com/telpo/beidouast/config/db/MongoDbContext.java new file mode 100644 index 0000000..14fbcd8 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/config/db/MongoDbContext.java @@ -0,0 +1,65 @@ +package com.telpo.dipperposition.config.db; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.data.mongodb.MongoDbFactory; +import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * @program: DataPushServer + * @description: mongdb数据库连接上下文 + * @author: linwl + * @create: 2020-07-11 14:31 + */ +@Component +public class MongoDbContext { + + private static final Map MONGO_CLIENT_DB_FACTORY_MAP = new HashMap<>(); + private static final ThreadLocal MONGO_DB_FACTORY_THREAD_LOCAL = new ThreadLocal<>(); + @Autowired + MongoListProperties mongoListProperties; + + public static MongoDbFactory getMongoDbFactory() { + return MONGO_DB_FACTORY_THREAD_LOCAL.get(); + } + + public static void setMongoDbFactory(String name) { + MONGO_DB_FACTORY_THREAD_LOCAL.set(MONGO_CLIENT_DB_FACTORY_MAP.get(name)); + } + + public static void removeMongoDbFactory() { + MONGO_DB_FACTORY_THREAD_LOCAL.remove(); + } + + @PostConstruct + public void afterPropertiesSet() { + if (!CollectionUtils.isEmpty(mongoListProperties.getDblist())) { + mongoListProperties + .getDblist() + .forEach( + info -> { + MONGO_CLIENT_DB_FACTORY_MAP.put( + info.getDatabase(), new SimpleMongoClientDbFactory(info.getUri())); + }); + } + } + + @Bean(name = "mongoTemplate") + public MultiMongoTemplate dynamicMongoTemplate() { + Iterator iterator = MONGO_CLIENT_DB_FACTORY_MAP.values().iterator(); + return new MultiMongoTemplate(iterator.next()); + } + + @Bean(name = "mongoDbFactory") + public MongoDbFactory mongoDbFactory() { + Iterator iterator = MONGO_CLIENT_DB_FACTORY_MAP.values().iterator(); + return iterator.next(); + } +} diff --git a/src/main/java/com/telpo/beidouast/config/db/MongoListProperties.java b/src/main/java/com/telpo/beidouast/config/db/MongoListProperties.java new file mode 100644 index 0000000..804eff3 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/config/db/MongoListProperties.java @@ -0,0 +1,30 @@ +package com.telpo.dipperposition.config.db; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.List; + +/** + * @program: DataPushServer + * @description: mongo连接配置类 + * @author: linwl + * @create: 2020-07-11 14:41 + */ +@Getter +@Setter +@ToString +@ConfigurationProperties(prefix = "mongo.datasource") +public class MongoListProperties { + + private List dblist; + + @Data + public static class MongoList { + private String uri; + private String database; + } +} diff --git a/src/main/java/com/telpo/beidouast/config/db/MultiMongoTemplate.java b/src/main/java/com/telpo/beidouast/config/db/MultiMongoTemplate.java new file mode 100644 index 0000000..df79df4 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/config/db/MultiMongoTemplate.java @@ -0,0 +1,26 @@ +package com.telpo.dipperposition.config.db; + +import com.mongodb.client.MongoDatabase; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.mongodb.MongoDbFactory; +import org.springframework.data.mongodb.core.MongoTemplate; + +/** + * @program: DataPushServer + * @description: 多mongo数据源配置 + * @author: linwl + * @create: 2020-07-11 14:21 + */ +@Slf4j +public class MultiMongoTemplate extends MongoTemplate { + + public MultiMongoTemplate(MongoDbFactory mongoDbFactory) { + super(mongoDbFactory); + } + + @Override + protected MongoDatabase doGetDatabase() { + MongoDbFactory mongoDbFactory = MongoDbContext.getMongoDbFactory(); + return mongoDbFactory == null ? super.doGetDatabase() : mongoDbFactory.getDb(); + } +} diff --git a/src/main/java/com/telpo/beidouast/controller/DipperPositionController.java b/src/main/java/com/telpo/beidouast/controller/DipperPositionController.java new file mode 100644 index 0000000..524256a --- /dev/null +++ b/src/main/java/com/telpo/beidouast/controller/DipperPositionController.java @@ -0,0 +1,26 @@ +package com.telpo.dipperposition.controller; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +/** + * @program: DipperPositionController + * @description: 北斗定位 + * @author: linwl + * @create: 2020-07-10 14:01 + */ +@RestController +@Slf4j +public class DipperPositionController { + @Value(value = "${position-server.serverAddr}") + private String hello; + //RzlAccount rzlAccount; + + @RequestMapping("/getPos") + public String getPos() { + return "return serverAddr = " + hello; + } +} diff --git a/src/main/java/com/telpo/beidouast/entity/mongo/IPProvinceEntity.java b/src/main/java/com/telpo/beidouast/entity/mongo/IPProvinceEntity.java new file mode 100644 index 0000000..d9f27df --- /dev/null +++ b/src/main/java/com/telpo/beidouast/entity/mongo/IPProvinceEntity.java @@ -0,0 +1,24 @@ +package com.telpo.dipperposition.entity.mongo; + +import com.telpo.dipperposition.vo.IPProvinceVo; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import models.BaseMongoDbEntity; + +/** + * @program: IPProvinceEntity + * @description: 位置实体类 + * @author: linwl + * @create: 2020-07-11 15:33 + */ +@ToString +@Getter +@Setter +public class IPProvinceEntity extends BaseMongoDbEntity { + + /** Ip */ + private String ip; + /** Ip所在省份 */ + private String province; +} diff --git a/src/main/java/com/telpo/beidouast/enums/DipperReturnValue.java b/src/main/java/com/telpo/beidouast/enums/DipperReturnValue.java new file mode 100644 index 0000000..68fa68f --- /dev/null +++ b/src/main/java/com/telpo/beidouast/enums/DipperReturnValue.java @@ -0,0 +1,53 @@ +package com.telpo.dipperposition.enums; + +/** + * @program: DipperReturnValue + * @description: 推送类型枚举 + * @author: king + * @create: 2021-01-24 11:44 + */ +public enum DipperReturnValue { + ACK(0, "SDBP-PUB–ACK"), + NACK(1, "SDBP-PUB–NACK"); + + /** 状态值 */ + private int value; + /** 描述 */ + private String describe; + + private DipperReturnValue(int value, String describe) { + this.value = value; + this.describe = describe; + } + + /** + * 获取推送类型 + * + * @param value + * @return + */ + public static DipperReturnValue getByValue(int value) { + for (DipperReturnValue enums : DipperReturnValue.values()) { + if (enums.getValue() == value) { + return enums; + } + } + return null; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + public String getDescribe() { + return describe; + } + + public void setDescribe(String describe) { + this.describe = describe; + } +} diff --git a/src/main/java/com/telpo/beidouast/handler/NettyServerHandler.java b/src/main/java/com/telpo/beidouast/handler/NettyServerHandler.java new file mode 100644 index 0000000..c552c23 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/handler/NettyServerHandler.java @@ -0,0 +1,181 @@ +package com.telpo.dipperposition.handler; + +import com.telpo.dipperposition.enums.DipperReturnValue; +import com.telpo.dipperposition.service.IDipperAstPosAsyncTaskService; +import com.telpo.dipperposition.service.IDipperAstTimeAsyncTaskService; +import com.telpo.dipperposition.service.IDipperDataAsyncTaskService; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; + +import java.io.InputStream; +import java.time.LocalDateTime; + +/** + * @program: dipperposition + * @description: Netty服务器处理句柄 + * @author: linwl + * @create: 2021-01-13 13:56 + **/ +@Slf4j +public class NettyServerHandler extends ChannelInboundHandlerAdapter { + + private static String AST_TIME_CMD = "54494d45"; + private static String AST_POS_CMD = "504f53"; + private static String AST_EPH_CMD = "455048"; + + @Autowired + private IDipperAstTimeAsyncTaskService dipperTimeAsyncTaskService; + @Autowired + private IDipperAstPosAsyncTaskService dipperAstPosAsyncTaskService; + @Autowired + private IDipperDataAsyncTaskService dipperDataAsyncTaskService; + + @Value(value = "${position-server.timeAsycPort}") + private String timeAsycServerPort; + + @Value(value = "${position-server.posAsycPort}") + private String posAsycServerPort; + + @Value(value = "${position-server.starsAsycPort}") + private String starsAsycServerPort; + + + @Value("${pos.centerProvinceFilePath}") + String centerProvinceFilePath; + + @Value("${pos.ipPositionRequestPath}") + String ipPositionRequestPath; + @Value("${pos.ipPositionRequestKey}") + String ipPositionRequestKey; + @Value("${pos.centerProvince}") + String centerProvince; + + + @Value("${pos.ast.server}") + String astServer; + @Value("${pos.ast.posAstPort}") + int posAstPort; + @Value("${pos.ast.timeout}") + int astTimeout; + /** + * 客户端连接会触发 + */ + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("Channel active......"); + + SocketChannel channel = (SocketChannel) ctx.channel(); + log.info("链接报告开始"); + log.info("链接报告信息:有一客户端链接到本服务端"); + log.info("链接报告IP:" + channel.localAddress().getHostString()); + log.info("链接报告Port:" + channel.localAddress().getPort()); + log.info("链接报告完毕"); + //通知客户端链接建立成功 + // 默认返回取得时间成功 + String ackAckCheckRef = "233E0101020004020A1D"; + if (Integer.parseInt(posAsycServerPort) == channel.localAddress().getPort()) { + ackAckCheckRef = "233E010102000401091C"; + } + if (Integer.parseInt(starsAsycServerPort) == channel.localAddress().getPort()) { + ackAckCheckRef = "233E010102000421293C"; + } + //String str = "通知客户端链接建立成功" + " " + LocalDateTime.now() + " " + channel.localAddress().getHostString() + + // "\r\n"; + ByteBuf buf = Unpooled.buffer(ackAckCheckRef.getBytes().length); + buf.writeBytes(ackAckCheckRef.getBytes("GBK")); + ctx.writeAndFlush(buf); + } + + + /** + * 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据 + */ + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("客户端断开链接,IP:{}", ctx.channel().localAddress().toString()); + } + + /** + * 客户端发消息会触发 + */ + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + //接收msg消息{与上一章节相比,此处已经不需要自己进行解码} + SocketChannel channel = (SocketChannel) ctx.channel(); + String ipAddress = channel.remoteAddress().toString(); + String message = " 接收到消息:{0}, 客户端IP:{1}"; + log.info(message ,msg, ipAddress); + + String channelAns = ""; + // 返回时间指令 + //if (Integer.parseInt(timeAsycServerPort) == channel.localAddress().getPort()) { + ByteBuf recvmg = (ByteBuf) msg; + ByteBuf buf = null; + String recvmgStr = recvmg.toString(); + if (AST_TIME_CMD.equals(recvmg)) { + // 初始时间辅助输入; + channelAns = dipperTimeAsyncTaskService.pushAstTime(); + buf = Unpooled.buffer(channelAns.getBytes().length); + } + + // 发送SDBP-AST-POS获取辅助位置信息 + // if (Integer.parseInt(posAsycServerPort) == channel.localAddress().getPort()) { + + if (AST_POS_CMD.equals(recvmg)) { + channelAns = dipperAstPosAsyncTaskService.pushAstPos(ipAddress, + centerProvinceFilePath, + centerProvince, + ipPositionRequestPath, + ipPositionRequestKey); + buf = Unpooled.buffer(channelAns.getBytes().length); + } + + // 从缓存获取SDBP-AST-EPH星历数 + //if (Integer.parseInt(starsAsycServerPort) == channel.localAddress().getPort()) { + if (AST_POS_CMD.equals(recvmg)) { + String astEPHBytes = dipperDataAsyncTaskService.getAstEPH(); + buf = Unpooled.buffer(astEPHBytes.getBytes().length); + } + + + // 最后把SDBP-AST-TIME、SDBP-AST-POS、SDBP-AST-EPH并包一起发给设备。 + // 设备采用16进制获取数据,则代理服务器也是采用16进制返回数据。 + // 通知客户端链消息发送成功 + // String str = "服务端收到:" + LocalDateTime.now() + " " + msg + "\r\n"; + buf.writeBytes(channelAns.getBytes("GBK")); + ctx.writeAndFlush(buf); + //ctx.write("你也好哦"); + //ctx.flush(); + } + +// @Override +// public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) +// throws Exception { +// if (msg instanceof HttpRequest) { +// HttpRequest mReq = (HttpRequest) msg; +// String clientIP = mReq.headers().get("X-Forwarded-For"); +// if (clientIP == null) { +// InetSocketAddress insocket = (InetSocketAddress) ctx.channel() +// .remoteAddress(); +// clientIP = insocket.getAddress().getHostAddress(); +// } +// } +// } + + /** + * 发生异常触发 + */ + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } + + +} diff --git a/src/main/java/com/telpo/beidouast/handler/ServerChannelInitializer.java b/src/main/java/com/telpo/beidouast/handler/ServerChannelInitializer.java new file mode 100644 index 0000000..95d98dd --- /dev/null +++ b/src/main/java/com/telpo/beidouast/handler/ServerChannelInitializer.java @@ -0,0 +1,24 @@ +package com.telpo.dipperposition.handler; + +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import io.netty.util.CharsetUtil; +/** + * @program: dipperposition + * @description: 服务器通道初始化 + * @author: king + * @create: 2021-01-13 13:54 + **/ +public class ServerChannelInitializer extends ChannelInitializer { + @Override + protected void initChannel(SocketChannel socketChannel) throws Exception { + //添加编解码 + socketChannel.pipeline().addLast("decoder", new StringDecoder(CharsetUtil.UTF_8)); + socketChannel.pipeline().addLast("encoder", new StringEncoder(CharsetUtil.UTF_8)); + socketChannel.pipeline().addLast(new NettyServerHandler()); + } + +} diff --git a/src/main/java/com/telpo/beidouast/mapper/IPProvinceMapper.java b/src/main/java/com/telpo/beidouast/mapper/IPProvinceMapper.java new file mode 100644 index 0000000..b050e1d --- /dev/null +++ b/src/main/java/com/telpo/beidouast/mapper/IPProvinceMapper.java @@ -0,0 +1,58 @@ +package com.telpo.dipperposition.mapper; + +import com.telpo.dipperposition.annotation.MongoSwitch; +import com.telpo.dipperposition.entity.mongo.IPProvinceEntity; +import db.BaseMongoDbDao; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * @program: DataPushServer + * @description: 推送记录mapper + * @author: linwl + * @create: 2020-07-20 11:12 + */ +@Repository +public class IPProvinceMapper extends BaseMongoDbDao { + + @Override + protected Class getEntityClass() { + return IPProvinceEntity.class; + } + + @Override + @MongoSwitch("common") + public void save(IPProvinceEntity entity, String collectionName) { + super.save(entity, collectionName); + } + + @Override + @MongoSwitch("common") + public void updateFirst(IPProvinceEntity srcObj, IPProvinceEntity targetObj) { + super.updateFirst(srcObj, targetObj); + } + + @Override + public List getPage(IPProvinceEntity object, int start, int size) { + return super.getPage(object, start, size); + } + + @Override + @MongoSwitch("common") + public List queryList(IPProvinceEntity object) { + return super.queryList(object); + } + + @Override + @MongoSwitch("common") + public List queryList(IPProvinceEntity object, String collectionName) { + return super.queryList(object, collectionName); + } + + @Override + @MongoSwitch("common") + public void deleteById(String id) { + super.deleteById(id); + } +} diff --git a/src/main/java/com/telpo/beidouast/server/DipperPositionServer.java b/src/main/java/com/telpo/beidouast/server/DipperPositionServer.java new file mode 100644 index 0000000..f81ddfc --- /dev/null +++ b/src/main/java/com/telpo/beidouast/server/DipperPositionServer.java @@ -0,0 +1,257 @@ +package com.telpo.dipperposition.server; + +import com.alibaba.nacos.api.NacosFactory; +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.exception.NacosException; +import com.telpo.dipperposition.co.PositionConfigInfo; +import com.telpo.dipperposition.handler.ServerChannelInitializer; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.env.ConfigurableEnvironment; + +import java.net.InetSocketAddress; + +/** + * @program: DipperPositionServer + * @description: 北斗定位 + * @author: king + * @create: 2021-01-13 14:01 + */ +@Slf4j +public class DipperPositionServer { + + // @Autowired PositionConfigInfo positionConfigInfo; + private String serverAddr; + private Integer serverPort; + private Integer timeAsycPort; + private Integer posAsycPort; + private Integer starsAsycPort; + + public DipperPositionServer(ConfigurableEnvironment environment) throws NacosException { + + this.serverAddr = environment.getProperty("position-server.serverAddr"); + this.serverPort = Integer.parseInt(environment.getProperty("server.port")); + this.timeAsycPort = Integer.parseInt(environment.getProperty("position-server.timeAsycPort")); + this.posAsycPort = Integer.parseInt(environment.getProperty("position-server.posAsycPort")); + this.starsAsycPort = Integer.parseInt(environment.getProperty("position-server.starsAsycPort")); + //String serverAddr = positionConfigInfo.getServerAddr(); +// try { +// try { +// InetAddress ip4 = Inet4Address.getLocalHost(); +// serverAddr = ip4.getHostAddress(); +// } catch (Exception ex) { +// serverAddr = "172.16.192.26"; +// ex.printStackTrace(); +// } +// String dataId = "dipperposition-service"; +// String group = "DEFAULT_GROUP"; +// Properties properties = new Properties(); +// properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr); +// ConfigService configService = NacosFactory.createConfigService(properties); +// String content = configService.getConfig(dataId, group, 5000); +// +// ByteArrayInputStream tInputStringStream = new ByteArrayInputStream(content.getBytes()); +// Yaml yaml = new Yaml(); +// Map m1 = yaml.load(tInputStringStream); +// Map m2 = (Map) m1.get("position-server"); +// this.serverAddr = (String)m2.get("serverAddr"); +// this.timeAsycPort = (Integer)m2.get("timeAsycPort"); +// this.posAsycPort = (Integer)m2.get("posAsycPort"); +// this.starsAsycPort = (Integer)m2.get("starsAsycPort"); +// log.info("Map server is:" + m2.get("serverAddr")); +// } catch (Exception ex) { +// ex.printStackTrace(); +// } + } +// /* +// * 时间同步进程线程 +// */ +// public void startTimeAsnc() { +// +// //new 一个主线程组 +// EventLoopGroup mainThreadGroup = new NioEventLoopGroup(1); +// //new 一个工作线程组 +// EventLoopGroup workThreadGroup = new NioEventLoopGroup(200); +// InetSocketAddress socketAddress = new InetSocketAddress(serverAddr, +// timeAsycPort); +// ServerBootstrap bootstrap = new ServerBootstrap() +// .group(mainThreadGroup, workThreadGroup) +// .channel(NioServerSocketChannel.class) +// .childHandler(new ServerChannelInitializer()) +// .localAddress(socketAddress) +// //设置队列大小 +// .option(ChannelOption.SO_BACKLOG, 1024) +// // 两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文 +// .childOption(ChannelOption.SO_KEEPALIVE, true); +// +// +// //绑定端口,开始接收进来的连接 +// try { +// ChannelFuture future = bootstrap.bind(socketAddress).sync(); +// log.info("服务器启动开始监听端口: {}", socketAddress.getPort()); +// +// +// future.channel().closeFuture().sync(); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } finally { +// //关闭主线程组 +// mainThreadGroup.shutdownGracefully(); +// //关闭工作线程组 +// workThreadGroup.shutdownGracefully(); +// } +// } + +// /* +// * 时间同步进程线程 +// */ +// public void startPosAsnc() { +// +// //new 一个主线程组 +// EventLoopGroup mainThreadGroup = new NioEventLoopGroup(1); +// //new 一个工作线程组 +// EventLoopGroup workThreadGroup = new NioEventLoopGroup(200); +// InetSocketAddress socketAddress = new InetSocketAddress(serverAddr, +// posAsycPort); +// ServerBootstrap bootstrap = new ServerBootstrap() +// .group(mainThreadGroup, workThreadGroup) +// .channel(NioServerSocketChannel.class) +// .childHandler(new ServerChannelInitializer()) +// .localAddress(socketAddress) +// //设置队列大小 +// .option(ChannelOption.SO_BACKLOG, 1024) +// // 两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文 +// .childOption(ChannelOption.SO_KEEPALIVE, true); +// +// +// //绑定端口,开始接收进来的连接 +// try { +// ChannelFuture future = bootstrap.bind(socketAddress).sync(); +// log.info("服务器启动开始监听端口: {}", socketAddress.getPort()); +// +// +// future.channel().closeFuture().sync(); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } finally { +// //关闭主线程组 +// mainThreadGroup.shutdownGracefully(); +// //关闭工作线程组 +// workThreadGroup.shutdownGracefully(); +// } +// } + + + /* + * 星历同步进程线程 + */ + //public void startStarsAsnc() { + public void start() { + + //new 一个主线程组 + EventLoopGroup mainThreadGroup = new NioEventLoopGroup(1); + //new 一个工作线程组 + EventLoopGroup workThreadGroup = new NioEventLoopGroup(200); + //InetSocketAddress socketAddress = new InetSocketAddress(serverAddr,null); + ServerBootstrap bootstrap = new ServerBootstrap() + .group(mainThreadGroup, workThreadGroup) + .channel(NioServerSocketChannel.class) + .childHandler(new ServerChannelInitializer()) + //.localAddress(socketAddress) + //设置队列大小 + .option(ChannelOption.SO_BACKLOG, 1024) + // 两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文 + .childOption(ChannelOption.SO_KEEPALIVE, true); + + + //绑定端口,开始接收进来的连接 + try { + ChannelFuture channelFuture = bootstrap.bind(timeAsycPort).sync(); + log.info("时间辅助服务器启动开始监听端口: {}", timeAsycPort); + channelFuture.addListener(future -> { + if (future.isSuccess()){ + System.out.println("start success"); + }else{ + System.out.println("start failed"); + } + }); + + ChannelFuture channelFuture2 = bootstrap.bind(posAsycPort).sync(); + log.info("位置服务器启动开始监听端口: {}", posAsycPort); + channelFuture2.addListener(future -> { + if (future.isSuccess()){ + System.out.println("start success"); + }else{ + System.out.println("start failed"); + } + }); + + + ChannelFuture channelFuture3 = bootstrap.bind(starsAsycPort).sync(); + log.info("星历服务器启动开始监听端口: {}", starsAsycPort); + channelFuture3.addListener(future -> { + if (future.isSuccess()){ + System.out.println("start success"); + }else{ + System.out.println("start failed"); + } + }); + + //channelFuture.channel().closeFuture().sync(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + //关闭主线程组 + mainThreadGroup.shutdownGracefully(); + //关闭工作线程组 + workThreadGroup.shutdownGracefully(); + } + } + + public void start2() { + + //new 一个主线程组 + EventLoopGroup mainThreadGroup = new NioEventLoopGroup(1); + //new 一个工作线程组 + EventLoopGroup workThreadGroup = new NioEventLoopGroup(200); + //InetSocketAddress socketAddress = new InetSocketAddress(serverAddr,null); + ServerBootstrap bootstrap = new ServerBootstrap() + .group(mainThreadGroup, workThreadGroup) + .channel(NioServerSocketChannel.class) + .childHandler(new ServerChannelInitializer()) + //.localAddress(socketAddress) + //设置队列大小 + .option(ChannelOption.SO_BACKLOG, 1024) + // 两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文 + .childOption(ChannelOption.SO_KEEPALIVE, true); + + + //绑定端口,开始接收进来的连接 + try { + ChannelFuture channelFuture = bootstrap.bind(timeAsycPort).sync(); + log.info("时间辅助服务器启动开始监听端口: {}", timeAsycPort); + channelFuture.addListener(future -> { + if (future.isSuccess()){ + System.out.println("start success"); + }else{ + System.out.println("start failed"); + } + }); + + //channelFuture.channel().closeFuture().sync(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + //关闭主线程组 + mainThreadGroup.shutdownGracefully(); + //关闭工作线程组 + workThreadGroup.shutdownGracefully(); + } + } +} diff --git a/src/main/java/com/telpo/beidouast/service/IDipperAstPosAsyncTaskService.java b/src/main/java/com/telpo/beidouast/service/IDipperAstPosAsyncTaskService.java new file mode 100644 index 0000000..dcc0cb8 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/service/IDipperAstPosAsyncTaskService.java @@ -0,0 +1,27 @@ +package com.telpo.dipperposition.service; + +import java.io.UnsupportedEncodingException; + +/** + * @program: IDipperAstPosAsyncTaskService + * @description: 系统预先基于省份的省会城市的经纬度作为辅助信息, + * 根据设备请求的IP地址,从高德IP定位服务获取相关的省份,再匹配相应的位置信息作为辅助位置信息。 + * 如果匹配不到省份,则以武汉中心作为辅助为位置信息。 + * 关于IP与省份的关系保存到缓存中,用于下次使用时,先在缓存中获取匹配信息,匹配不到,再请求高德IP定位服务。 + * 高德IP定位服务:https://lbs.amap.com/api/webservice/guide/api/ipconfig。 + * @author: king + * @create: 2021-01-17 16:24 + */ +public interface IDipperAstPosAsyncTaskService { + + /** + * 同步任务 + * + */ + String pushAstPos(String ipAddress, + String centerProvinceFilePath, + String centerProvince, + String ipPositionRequestPath, + String ipPositionRequestKey) throws UnsupportedEncodingException; + +} diff --git a/src/main/java/com/telpo/beidouast/service/IDipperAstTimeAsyncTaskService.java b/src/main/java/com/telpo/beidouast/service/IDipperAstTimeAsyncTaskService.java new file mode 100644 index 0000000..5dfeb0e --- /dev/null +++ b/src/main/java/com/telpo/beidouast/service/IDipperAstTimeAsyncTaskService.java @@ -0,0 +1,17 @@ +package com.telpo.dipperposition.service; + +/** + * @program: IDipperDataAsyncTaskService + * @description: 发送SDBP-AST-TIME获取时间信息 + * @author: king + * @create: 2021-01-17 16:24 + */ +public interface IDipperAstTimeAsyncTaskService { + + /** + * 同步任务 + * + */ + String pushAstTime(); + +} diff --git a/src/main/java/com/telpo/beidouast/service/IDipperDataAsyncTaskService.java b/src/main/java/com/telpo/beidouast/service/IDipperDataAsyncTaskService.java new file mode 100644 index 0000000..708e6df --- /dev/null +++ b/src/main/java/com/telpo/beidouast/service/IDipperDataAsyncTaskService.java @@ -0,0 +1,28 @@ +package com.telpo.dipperposition.service; + +import org.springframework.beans.factory.annotation.Value; + +/** + * @program: IDipperDataAsyncTaskService + * @description: 发送bds获取星历数据。 + * * 每30分钟获取1次,30秒超时, + * * 如果失败,则可以等待10秒再获取1次 + * @author: king + * @create: 2021-01-17 16:24 + */ +public interface IDipperDataAsyncTaskService { + + /** + * 同步任务 + * + */ + void pullAstEPH(); + + + /** + * 根据IP获取EPH + * + */ + String getAstEPH(); + +} diff --git a/src/main/java/com/telpo/beidouast/service/IPProvinceService.java b/src/main/java/com/telpo/beidouast/service/IPProvinceService.java new file mode 100644 index 0000000..f8e3c66 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/service/IPProvinceService.java @@ -0,0 +1,45 @@ +package com.telpo.dipperposition.service; + +import com.telpo.dipperposition.entity.mongo.IPProvinceEntity; +import com.telpo.dipperposition.vo.IPProvinceVo; + +/** + * @program: IPProvinceService + * @description: IP省份服务接口 + * @author: king + * @create: 2020-07-20 11:09 + */ +public interface IPProvinceService { + + /** + * 保存IP省份 + * + * @param entity + * @return + */ + boolean saveIPProvince(IPProvinceEntity entity); + + /** + * 更新IP省份 + * + * @param query + * @param update + * @return + */ + boolean updateIPProvince( + IPProvinceEntity query, IPProvinceEntity update); + + /** + * 根据ID移除IP省份记录 + * + * @param id + * @return + */ + boolean romveById(String id); + + /* + * @param ipAddress + * 获取IP省份 + */ + IPProvinceEntity getIPProvince(String ipAddress); +} diff --git a/src/main/java/com/telpo/beidouast/service/impl/DipperAstPosAsyncTaskServiceImpl.java b/src/main/java/com/telpo/beidouast/service/impl/DipperAstPosAsyncTaskServiceImpl.java new file mode 100644 index 0000000..4b100eb --- /dev/null +++ b/src/main/java/com/telpo/beidouast/service/impl/DipperAstPosAsyncTaskServiceImpl.java @@ -0,0 +1,247 @@ +package com.telpo.dipperposition.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.google.common.base.Joiner; +import com.telpo.dipperposition.common.*; +import com.telpo.dipperposition.entity.mongo.IPProvinceEntity; +import com.telpo.dipperposition.mapper.IPProvinceMapper; +import com.telpo.dipperposition.service.IDipperAstPosAsyncTaskService; +import com.telpo.dipperposition.service.IPProvinceService; +import com.telpo.dipperposition.vo.IPProvinceVo; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.io.UnsupportedEncodingException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +/** + * @program: DipperAstPosAsyncTaskServiceImpl + * @description: 系统预先基于省份的省会城市的经纬度作为辅助信息, + * * 根据设备请求的IP地址,从高德IP定位服务获取相关的省份,再匹配相应的位置信息作为辅助位置信息。 + * * 如果匹配不到省份,则以武汉中心作为辅助为位置信息。 + * * 关于IP与省份的关系保存到缓存中,用于下次使用时,先在缓存中获取匹配信息,匹配不到,再请求高德IP定位服务。 + * * 高德IP定位服务:https://lbs.amap.com/api/webservice/guide/api/ipconfig。 + * @author: king + * @create: 2021-01-10 14:01 + */ +@Service +@Slf4j +public class DipperAstPosAsyncTaskServiceImpl implements IDipperAstPosAsyncTaskService { + + @Autowired + private RedisUtil redisUtil; + @Autowired + private OkHttpUtil okHttpUtil; + @Autowired + private IPProvinceService iPProvinceService; + + private String centerProvince; + private String centerProvinceFilePath; + private String ipPositionRequestPath; + private String ipPositionRequestKey; +// private String getAstPos(String ipAddress) throws UnsupportedEncodingException { +// +// String centerAddress = getIpPositionProvince(ipAddress); +// if (ObjectUtils.isEmpty(centerAddress) || centerAddress.equals("0")) { +// log.warn("IP地址非法,无法获取辅助位置信息!"); +// // 返回武汉的定位数据 +// centerAddress = centerProvince; +// } else { +// // 保存到mongoDB +// createIPProvince(ipAddress, centerAddress); +// } +// +// String lonAndAlt; +// if (redisUtil.hasKey(centerAddress)) { +// // 获取省会城市定位信息 +// lonAndAlt= (String) redisUtil.get(centerAddress); +// } else { +// // 请求高德IP定位服务 +// this.getPosFromFile(centerAddress); +// lonAndAlt = (String) redisUtil.get(centerAddress); +// } +// +// return lonAndAlt; +// } + + // 从CSV文件读取省会城市中心点位置信息 + private void getPosFromFile(String centerAddress) { + // 不存在说明token是已过期了 + String centerProvinceName = ""; + String centerProvinceLonAndAlt = ""; + List centerAddressSets = CSVUtil.readCSV(this.centerProvinceFilePath); + for (String centerAddressSet:centerAddressSets) { + String[] centerAddressSetArray = centerAddressSet.split(","); + if (centerAddressSetArray.length < 3) { + log.warn("CSV数据格式错误"); + } else { + centerProvinceName = centerAddressSetArray[3]; + centerProvinceLonAndAlt = centerAddressSetArray[1]+","+centerAddressSetArray[2]; + redisUtil.set(centerProvinceName, centerProvinceLonAndAlt, 0); + } + } + } + + // 根据IP获取省会信息 + private String getIpPositionProvince(String ipAddress) { + + // 关于IP与省份的关系保存到缓存中 + // 使用时,先在缓存中获取匹配信息 + // 用mongodb实现 + IPProvinceEntity ipProvinceEntity = iPProvinceService.getIPProvince(ipAddress); + if (ipProvinceEntity == null) { + // 匹配不到,再请求高德IP定位服务。 + JSONObject userObj = new JSONObject(); + userObj.put("ip", ipAddress); + userObj.put("key", ipPositionRequestKey); + + JSONObject json = okHttpUtil.postRequestWithJson(ipPositionRequestPath, null, userObj); + if (ObjectUtils.isNotEmpty(json)) { + String province = (String) json.get("province"); + if (ObjectUtils.isEmpty(province)) { + log.debug("json is :" + json.toString()); + return null; + } + return province; + } else { + // 意外错误 + log.debug("ip address is null"); + return null; + } + } else { + return ipProvinceEntity.getProvince(); + } + } + + // 将IP对应的省会保存到mongoDB + @Async("asyncServiceExecutor") + public void createIPProvince(String ipAddress, String province) { + log.debug("异步创建推送失败任务记录!"); + try { + IPProvinceEntity ipProvinceEntity = iPProvinceService.getIPProvince(ipAddress); + if (ipProvinceEntity == null) { + //DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + ipProvinceEntity.setIp(ipAddress); + ipProvinceEntity.setProvince(province); + iPProvinceService.saveIPProvince(ipProvinceEntity); +// } else { +// +// ipProvinceEntity.setProvince(province); +// iPProvinceService.updateIPProvince(ipProvinceEntity, ipProvinceEntity); + } + } catch (Exception e) { + log.error("创建推送失败记录异常:", e); + } + } + + /* + * 获取定位辅助信息 + * @param ipAddress + */ + @Override + @Async("asyncServiceExecutor") + public String pushAstPos(String ipAddress, + String centerProvinceFilePath, + String centerProvince, + String ipPositionRequestPath, + String ipPositionRequestKey) throws UnsupportedEncodingException { + this.ipPositionRequestKey = ipPositionRequestKey; + this.ipPositionRequestPath = ipPositionRequestPath; + this.centerProvince = centerProvince; + this.centerProvinceFilePath = centerProvinceFilePath; + // (1) 获取省会城市信息 + String centerAddress = getIpPositionProvince(ipAddress); + if (ObjectUtils.isEmpty(centerAddress) || centerAddress.equals("0")) { + log.warn("IP地址非法,无法获取辅助位置信息!"); + // 返回武汉的定位数据 + centerAddress = this.centerProvince; + } else { + // 保存到mongoDB + createIPProvince(ipAddress, centerAddress); + } + + String lonAndAlt; + if (redisUtil.hasKey(centerAddress)) { + // 获取省会城市定位信息 + lonAndAlt= (String) redisUtil.get(centerAddress); + } else { + // 请求高德IP定位服务 + this.getPosFromFile(centerAddress); + lonAndAlt = (String) redisUtil.get(centerAddress); + } + + // (2) 处理返回结果 + if (lonAndAlt == null) { + // null处理 + log.error("系统错误,请联系系统管理员。"); + return null; + //return; + } + + // push to GNNS Server + String pushResult = getCmdOfPos(lonAndAlt); + return pushResult; + } + + // 组装命令发送给设备 + private String getCmdOfPos(String astPos) { + + // 创建Socket客户端实例; + // SocketClient client = new SocketClient(astServer, posAstPort, astTimeout); + + // 时间和位置不是从服务器获取,而是本地生成 + String[] astPosArray = astPos.split(","); + String lan = astPosArray[0].trim(); + String alt = astPosArray[1].trim(); + double lanValue = Double.parseDouble(lan) * 10000000; + long lanLongValue = Double.doubleToLongBits(lanValue); + if (lanLongValue < 0) { + lanLongValue = lanLongValue + 4294967295L + 1; + } + double altValue = Double.parseDouble(alt) * 10000000; + long altLongValue = Double.doubleToLongBits(altValue); + if (altLongValue < 0) { + altLongValue = altLongValue + 4294967295L + 1; + } + // 数值换算举例(以经度举例。纬度、高度、位置精度换算方法一致): + // (1)经度数值为 113.431,则换算方法如下: + // 113.431/比例因子 = 1134310000(十进制) + //  439C3270(十六进制) + //  经度数据填入 70 32 9C 43(小端模式) + // (2)经度数值为-113.431,则换算方法如下: + // 113.431/比例因子 = 1134310000(十进制) + //  439C3270(十六进制) + //  FFFFFFFF - 439C3270 + 1= BC63CD90(补码) + // 经度数据填入 90 CD 63 BC(小端模式) + // 指令(十六进制) + // 举例: 23 3E 04 01 10 00 70 32 9C 43 D0 B2 CE 0D 70 17 00 00 40 0D 03 00 CA 95 + // 其中 + // 23 3E 为同步头 + // 04 01 为识别码 + // 10 00 表示长度为 16 + // 70 32 9C 43 表示注入的辅助经度为 113.431 度 + // D0 B2 CE 0D 表示注入的辅助纬度为 23.165 度 + // 00 2F 为校验和 + + // astTimeCmd 组装 + String astTimeCmd = "233E0401"; + astTimeCmd += "1000"; + astTimeCmd += HexConvert.encodeHEX(lanLongValue); + astTimeCmd += HexConvert.encodeHEX(altLongValue); + + String hexIn = HexConvert.convertStringToHex(astTimeCmd) + HexConvert.makeChecksum(astTimeCmd); + + //String sendResult = client.sendCmd(hexIn, ackAckCheckRef); + //client.closeConnection(); + + //return sendResult; + return hexIn; + } +} diff --git a/src/main/java/com/telpo/beidouast/service/impl/DipperAstTimeAsyncTaskServiceImpl.java b/src/main/java/com/telpo/beidouast/service/impl/DipperAstTimeAsyncTaskServiceImpl.java new file mode 100644 index 0000000..1ae8c2d --- /dev/null +++ b/src/main/java/com/telpo/beidouast/service/impl/DipperAstTimeAsyncTaskServiceImpl.java @@ -0,0 +1,106 @@ +package com.telpo.dipperposition.service.impl; + +import com.telpo.dipperposition.common.HexConvert; +import com.telpo.dipperposition.common.SocketClient; +import com.telpo.dipperposition.service.IDipperAstTimeAsyncTaskService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + +/** + * @program: DipperDataAsyncTaskServiceImpl + * @description: 发送SDBP-AST-TIME获取时间信息 + * @author: king + * @create: 2021-01-10 14:01 + */ +@Service +@Slf4j +public class DipperAstTimeAsyncTaskServiceImpl implements IDipperAstTimeAsyncTaskService { + + @Override + @Async("asyncServiceExecutor") + public String pushAstTime() { + + // (1) 发送SDBP-AST-TIME + // String sendResult = pushTimeToDipper(); + //if (sendResult == null) { + // log.error("取不到时间。"); + // return null; + //} + + // (2) 获取时间信息 + return pushTimeToDipper(); + //return sendResult; + } + + private String pushTimeToDipper() { + + // 创建Socket客户端实例; + // SocketClient client = new SocketClient(astServer, timeAstPort, astTimeout); + + // 时间和位置不是从服务器获取,而是本地生成(其中时间误差不超过3s) + // 23 3E 04 02 10 00 20 E1 07 09 14 0C 22 38 00 00 00 00 00 28 6B EE 22 98 + // 23 3E 为同步头 + // 04 02 为识别码 + // 10 00 表示长度为 16 + // --日期-- + // 20 E1 表示闰秒改正数为 + // E1 07 表示年为 2017 年(十六进制 07E1 转为十进制) + // 09 表示 9 月 + // 14 表示 20 日 + // 0C 22 38 00 00 00 00 00 表示 UTC时间,为12时34分56.0秒(小数秒建议固定为 0) + // 00 28 6B EE 表示 4 秒的时间精度(十六进制 EE6B2800 转为十进制为 4000000000,乘以比 例因子 10-9就是 4 秒) + // 00 2F 为校验和 + // TODO astTimeCmd 组装 + String astTimeCmd = "233E0402"; + astTimeCmd += "1000"; + astTimeCmd += "20E1"; + LocalDateTime now = LocalDateTime.now(); + int year = now.getYear(); + int month = now.getMonthValue(); + int day = now.getDayOfMonth(); + String hexYearString = Integer.toHexString(year); + hexYearString = "0" + hexYearString; + astTimeCmd += hexYearString.substring(2,2) + hexYearString.substring(0,2); + String hexMonthString = Integer.toHexString(month); + hexMonthString = "0" + hexMonthString; + astTimeCmd += hexMonthString; + String hexDayString = Integer.toHexString(day); + if (day < 16) { + hexDayString = "0" + hexDayString; + } + astTimeCmd += hexDayString; + + int hour = now.getHour(); + int minitor = now.getMinute(); + int second = now.getSecond(); + String hexHourString = Integer.toHexString(hour); + if (hour < 16) { + hexHourString = "0" + hexHourString; + } + astTimeCmd += hexHourString; + String hexMinitorString = Integer.toHexString(minitor); + if (minitor < 16) { + hexMinitorString = "0" + hexMinitorString; + } + astTimeCmd += hexMinitorString; + String hexSecondString = Integer.toHexString(second); + if (second < 16) { + hexSecondString = "0" + hexSecondString; + } + astTimeCmd += hexSecondString; + astTimeCmd += "0000000000"; + astTimeCmd += "00286BEE"; + + String hexIn = HexConvert.convertStringToHex(astTimeCmd) + HexConvert.makeChecksum(astTimeCmd); + + //String ackAckCheckRef = "233E0101020004020A1D"; + //String sendResult = client.sendCmd(hexIn, ackAckCheckRef); + //client.closeConnection(); + + return hexIn; + } +} diff --git a/src/main/java/com/telpo/beidouast/service/impl/DipperDataAsyncTaskServiceImpl.java b/src/main/java/com/telpo/beidouast/service/impl/DipperDataAsyncTaskServiceImpl.java new file mode 100644 index 0000000..aec944e --- /dev/null +++ b/src/main/java/com/telpo/beidouast/service/impl/DipperDataAsyncTaskServiceImpl.java @@ -0,0 +1,68 @@ +package com.telpo.dipperposition.service.impl; + +import com.telpo.dipperposition.common.HexConvert; +import com.telpo.dipperposition.common.RedisUtil; +import com.telpo.dipperposition.common.SocketClient; +import com.telpo.dipperposition.config.SchedulingExecutorConfig; +import com.telpo.dipperposition.service.IDipperDataAsyncTaskService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +/** + * @program: DipperDataAsyncTaskServiceImpl + * @description: 获取星历数据。 + * @author: king + * @create: 2021-01-10 14:01 + */ +@Service +@Slf4j +public class DipperDataAsyncTaskServiceImpl implements IDipperDataAsyncTaskService { + + + private static String DIPPER_DATA_KEY = "TaidouDipperData"; + private static String DIPPER_ALL_DATA_REQ = "616C6C"; + + @Autowired + private RedisUtil redisUtil; + @Autowired + private SchedulingExecutorConfig schedulingExecutorConfig; + + @Override + public void pullAstEPH() { + // (1) 发送bds获取星历数据 + String dipperData = pullEPHFromDipper(); + + // (2) 获取星历数据 + if (dipperData == null) { + log.error("获取星历数据错误,取不到星历数据。"); + } else { + // 保存到DB或者缓存 + redisUtil.set(DIPPER_DATA_KEY,dipperData); + } + } + + + private String pullEPHFromDipper() { + + // 创建Socket客户端实例; + SocketClient client = new SocketClient(schedulingExecutorConfig.getAstServer(), schedulingExecutorConfig.getEphAstHexPort(),schedulingExecutorConfig.getAstTimeout()); + + // astTimeCmd 组装 + String astTimeCmd = DIPPER_ALL_DATA_REQ; + String hexIn = astTimeCmd + HexConvert.makeChecksum(astTimeCmd); + + String ackAckCheckRef = "233E010102000421293C"; + String sendResult = client.sendCmd(hexIn, ackAckCheckRef); + client.closeConnection(); + + return sendResult; + } + + @Override + @Async("asyncServiceExecutor") + public String getAstEPH(){ + return (String)redisUtil.get(DIPPER_DATA_KEY); + } +} diff --git a/src/main/java/com/telpo/beidouast/service/impl/IPProvinceServiceImpl.java b/src/main/java/com/telpo/beidouast/service/impl/IPProvinceServiceImpl.java new file mode 100644 index 0000000..ca2de93 --- /dev/null +++ b/src/main/java/com/telpo/beidouast/service/impl/IPProvinceServiceImpl.java @@ -0,0 +1,62 @@ +package com.telpo.dipperposition.service.impl; + +import com.telpo.dipperposition.entity.mongo.IPProvinceEntity; +import com.telpo.dipperposition.mapper.IPProvinceMapper; +import com.telpo.dipperposition.service.IPProvinceService; +import com.telpo.dipperposition.vo.IPProvinceVo; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @program: DataPushServer + * @description: 推送记录服务接口实现类 + * @author: linwl + * @create: 2020-07-20 11:09 + */ +@Slf4j +@Service +public class IPProvinceServiceImpl implements IPProvinceService { + + @Autowired + private IPProvinceMapper iPProvinceMapper; + + @Override + public boolean saveIPProvince(IPProvinceEntity entity) { + iPProvinceMapper.save(entity); + return true; + } + + @Override + public boolean updateIPProvince( + IPProvinceEntity query, IPProvinceEntity update) { + iPProvinceMapper.updateFirst(query, update); + return true; + } + + @Override + public boolean romveById(String id) { + iPProvinceMapper.deleteById(id); + return false; + } + + @Override + public IPProvinceEntity getIPProvince(String ipAddress) { + try { + IPProvinceEntity query = new IPProvinceEntity(); + query.setIp(ipAddress); + List pushRecords = iPProvinceMapper.queryList(query); + if (ObjectUtils.isNotEmpty(pushRecords)) { + return pushRecords.get(0); + } else { + return null; + } + } catch (Exception e) { + log.error("获取IP省份异常:", e); + return null; + } + } +} diff --git a/src/main/java/com/telpo/beidouast/task/ScheduleService.java b/src/main/java/com/telpo/beidouast/task/ScheduleService.java new file mode 100644 index 0000000..54e151e --- /dev/null +++ b/src/main/java/com/telpo/beidouast/task/ScheduleService.java @@ -0,0 +1,40 @@ +package com.telpo.dipperposition.task; + +import com.telpo.dipperposition.service.IDipperDataAsyncTaskService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + + +/** + * @program: ScheduleService + * @description: 定时执行任务服务 + * @author: king + * @create: 2021-01-17 16:24 + */ +@Component +@Slf4j +public class ScheduleService { + + @Autowired + private IDipperDataAsyncTaskService dipperDataAsyncTaskService; + + /* + * 调用9012端口的接口获取星历数据。 + * 通过TCP连接服务器agnss.techtotop.com:9012,发送bds获取星历数据。 + * 每30分钟获取1次,30秒超时, + * 如果失败,则可以等待10秒再获取1次。 * + */ + @Scheduled(cron = "${scheduler.task.cron}") + public void pullData() { + log.info("开始星历数据同步!"); + // 获取推送失败的记录 + try { + dipperDataAsyncTaskService.pullAstEPH(); + } catch (Exception e) { + log.error("执行定时获取星历数据发生异常:", e); + } + } +} diff --git a/src/main/java/com/telpo/beidouast/vo/IPProvinceVo.java b/src/main/java/com/telpo/beidouast/vo/IPProvinceVo.java new file mode 100644 index 0000000..df9abeb --- /dev/null +++ b/src/main/java/com/telpo/beidouast/vo/IPProvinceVo.java @@ -0,0 +1,20 @@ +package com.telpo.dipperposition.vo; + +import lombok.Getter; +import lombok.Setter; + +/** + * @program: DataPushServer + * @description: 基础类 + * @author: linwl + * @create: 2020-07-17 16:41 + */ +@Setter +@Getter +public class IPProvinceVo { + + /** Ip */ + private String ip; + /** Ip所在省份 */ + private String province; +} diff --git a/src/main/resources/bootstrap.yaml b/src/main/resources/bootstrap.yaml new file mode 100644 index 0000000..eafa131 --- /dev/null +++ b/src/main/resources/bootstrap.yaml @@ -0,0 +1,69 @@ +logging: + config: classpath:log/logback-spring.xml + level: + com: + telpo: + dipperposition: debug +spring: + application: + name: dipperposition-service + redis: + database: 1 + host: 172.16.192.26 + port: 8090 + password: telpo#1234 + timeout: 3000 + lettuce: + pool: + max-active: 100 # 连接池最大连接数(使用负值表示没有限制) + max-idle: 100 # 连接池中的最大空闲连接 + min-idle: 50 # 连接池中的最小空闲连接 + max-wait: 6000 # 连接池最大阻塞等待时间(使用负值表示没有限制) + +scheduler: + pool: + size: 2 + #等待任务完成退出最大秒数 + await-seconds: 600 + task: + cron: "0 0 1 * * ?" + +pos: + centerProvinceFilePath: /csv/provinceLonAlt.csv + ipPositionRequestPath: https://restapi.amap.com/v3/ip + ipPositionRequestKey: 65e794b0a1a4b87eeec86f93fea05411 + centerProvince: 湖北省 + ast: + server: agnss.techtotop.com + ephAstPort: 8012 + ephAstHexPort: 9012 + timeout: 30000 + +position-server: + serverAddr: localhost + timeAsycPort: 9011 + posAsycPort: 9013 + starsAsycPort: 9012 + +mongo: + datasource: + dblist: + - uri: mongodb://wangjx:wangjx#1234@172.16.192.26:27017/basicdata + database: basicdata + - uri: mongodb://wangjx:wangjx#1234@172.16.192.26:27017/common + database: common + + +OkHttp-config: + pool: + max-conn: 200 + keep-alive: 5 + read-timeout: 10 + conn-timeout: 10 + write-timeout: 10 + +async: + pool: + corePoolSize: 4 + maxPoolSize: 8 + queueCapacity: 5000 \ No newline at end of file diff --git a/src/main/resources/csv/provinceLonAlt.csv b/src/main/resources/csv/provinceLonAlt.csv new file mode 100644 index 0000000..9904ec8 --- /dev/null +++ b/src/main/resources/csv/provinceLonAlt.csv @@ -0,0 +1,35 @@ +城市,经度,纬度,省份 +沈阳市,123.429092,41.796768,辽宁省 +长春市,125.324501,43.886841,吉林省 +哈尔滨市,126.642464,45.756966,黑龙江省 +北京市,116.405289,39.904987,北京市 +天津市,117.190186,39.125595,天津市 +呼和浩特市,111.75199,40.84149,内蒙古自治区 +银川市,106.23248,38.48644,宁夏回族自治区 +太原市,112.549248,37.857014,山西省 +石家庄市,114.502464,38.045475,河北省 +济南市,117.000923,36.675808,山东省 +郑州市,113.665413,34.757977,河南省 +西安市,108.948021,34.263161,陕西省 +武汉市,114.298569,30.584354,湖北省 +南京市,118.76741,32.041546,江苏省 +合肥市,117.283043,31.861191,安徽省 +上海市,121.472641,31.231707,上海市 +长沙市,112.982277,28.19409,湖南省 +南昌市,115.892151,28.676493,江西省 +杭州市,120.15358,30.287458,浙江省 +福州市,119.306236,26.075302,福建省 +广州市,113.28064,23.125177,广东省 +台北市,121.520076,25.030724,台湾省 +海口市,110.19989,20.04422,海南省 +南宁市,108.320007,22.82402,广西壮族自治区 +重庆市,106.504959,29.533155,重庆市 +昆明市,102.71225,25.040609,云南省 +贵阳市,106.713478,26.578342,贵州省 +成都市,104.065735,30.659462,四川省 +兰州市,103.83417,36.06138,甘肃省 +西宁市,101.77782,36.61729,青海省 +拉萨市,91.1145,29.64415,西藏自治区 +乌鲁木齐市,87.61688,43.82663,新疆维吾尔自治区 +香港,114.16546,22.27534,香港特别行政区 +澳门,113.54913,22.19875,澳门特别行政区 diff --git a/src/main/resources/log/logback-spring.xml b/src/main/resources/log/logback-spring.xml new file mode 100644 index 0000000..4b080ce --- /dev/null +++ b/src/main/resources/log/logback-spring.xml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + debug + + + ${CONSOLE_LOG_PATTERN} + + UTF-8 + + + + + + + + + + ${log.path}/log_debug.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + + ${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log + + 100MB + + + 15 + + + + debug + ACCEPT + DENY + + + + + + + ${log.path}/log_info.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + + ${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log + + 100MB + + + 15 + + + + info + ACCEPT + DENY + + + + + + + ${log.path}/log_warn.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + ${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log + + 100MB + + + 15 + + + + warn + ACCEPT + DENY + + + + + + + + ${log.path}/log_error.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + ${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log + + 100MB + + + 15 + + + + ERROR + ACCEPT + DENY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file