From 0d6b255922a4cfc4801a917ac06440da37cd7b67 Mon Sep 17 00:00:00 2001
From: linwl <304115325@qq.com>
Date: Fri, 15 Jan 2021 12:27:42 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=85=8D=E7=BD=AE=E6=96=87?=
=?UTF-8?q?=E4=BB=B6=E8=AF=BB=E5=8F=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 45 ++
.../DipperPositionApplication.java | 10 +
.../telpo/dipperposition/common/CSVUtil.java | 87 +++
.../dipperposition/common/HexConvert.java | 140 ++++
.../dipperposition/common/OkHttpUtil.java | 155 ++++
.../dipperposition/common/RedisUtil.java | 665 ++++++++++++++++++
.../dipperposition/common/SocketClient.java | 85 +++
.../dipperposition/common/TimeTools.java | 39 +
.../dipperposition/config/PositionConfig.java | 11 -
.../config/db/MongoDbContext.java | 66 ++
.../config/db/MongoListProperties.java | 30 +
.../config/db/MultiMongoTemplate.java | 26 +
.../controller/DipperPositionController.java | 32 +-
.../entity/mongo/IPProvinceEntity.java | 24 +
.../enums/DipperReturnValue.java | 53 ++
.../handler/NettyServerHandler.java | 145 ++++
.../handler/ServerChannelInitializer.java | 24 +
.../mapper/IPProvinceMapper.java | 52 ++
.../server/DipperPositionServer.java | 153 ++++
.../IDipperAstPosAsyncTaskService.java | 23 +
.../IDipperAstTimeAsyncTaskService.java | 17 +
.../service/IDipperDataAsyncTaskService.java | 26 +
.../service/IPProvinceService.java | 45 ++
.../DipperAstPosAsyncTaskServiceImpl.java | 251 +++++++
.../DipperAstTimeAsyncTaskServiceImpl.java | 104 +++
.../impl/DipperDataAsyncTaskServiceImpl.java | 73 ++
.../service/impl/IPProvinceServiceImpl.java | 62 ++
.../dipperposition/task/ScheduleService.java | 39 +
.../telpo/dipperposition/vo/IPProvinceVo.java | 20 +
src/main/resources/bootstrap.yaml | 26 +-
30 files changed, 2486 insertions(+), 42 deletions(-)
create mode 100644 src/main/java/com/telpo/dipperposition/common/CSVUtil.java
create mode 100644 src/main/java/com/telpo/dipperposition/common/HexConvert.java
create mode 100644 src/main/java/com/telpo/dipperposition/common/OkHttpUtil.java
create mode 100644 src/main/java/com/telpo/dipperposition/common/RedisUtil.java
create mode 100644 src/main/java/com/telpo/dipperposition/common/SocketClient.java
create mode 100644 src/main/java/com/telpo/dipperposition/common/TimeTools.java
create mode 100644 src/main/java/com/telpo/dipperposition/config/db/MongoDbContext.java
create mode 100644 src/main/java/com/telpo/dipperposition/config/db/MongoListProperties.java
create mode 100644 src/main/java/com/telpo/dipperposition/config/db/MultiMongoTemplate.java
create mode 100644 src/main/java/com/telpo/dipperposition/entity/mongo/IPProvinceEntity.java
create mode 100644 src/main/java/com/telpo/dipperposition/enums/DipperReturnValue.java
create mode 100644 src/main/java/com/telpo/dipperposition/handler/NettyServerHandler.java
create mode 100644 src/main/java/com/telpo/dipperposition/handler/ServerChannelInitializer.java
create mode 100644 src/main/java/com/telpo/dipperposition/mapper/IPProvinceMapper.java
create mode 100644 src/main/java/com/telpo/dipperposition/server/DipperPositionServer.java
create mode 100644 src/main/java/com/telpo/dipperposition/service/IDipperAstPosAsyncTaskService.java
create mode 100644 src/main/java/com/telpo/dipperposition/service/IDipperAstTimeAsyncTaskService.java
create mode 100644 src/main/java/com/telpo/dipperposition/service/IDipperDataAsyncTaskService.java
create mode 100644 src/main/java/com/telpo/dipperposition/service/IPProvinceService.java
create mode 100644 src/main/java/com/telpo/dipperposition/service/impl/DipperAstPosAsyncTaskServiceImpl.java
create mode 100644 src/main/java/com/telpo/dipperposition/service/impl/DipperAstTimeAsyncTaskServiceImpl.java
create mode 100644 src/main/java/com/telpo/dipperposition/service/impl/DipperDataAsyncTaskServiceImpl.java
create mode 100644 src/main/java/com/telpo/dipperposition/service/impl/IPProvinceServiceImpl.java
create mode 100644 src/main/java/com/telpo/dipperposition/task/ScheduleService.java
create mode 100644 src/main/java/com/telpo/dipperposition/vo/IPProvinceVo.java
diff --git a/pom.xml b/pom.xml
index 382d7f3..20c8038 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,6 +87,51 @@
1.2.28
+
+ io.netty
+ netty-all
+ 4.1.13.Final
+
+
+
+ com.telpo
+ common
+ 1.1.19
+
+
+
+
+ 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
+
+
diff --git a/src/main/java/com/telpo/dipperposition/DipperPositionApplication.java b/src/main/java/com/telpo/dipperposition/DipperPositionApplication.java
index 5bafebb..865170a 100644
--- a/src/main/java/com/telpo/dipperposition/DipperPositionApplication.java
+++ b/src/main/java/com/telpo/dipperposition/DipperPositionApplication.java
@@ -1,11 +1,15 @@
package com.telpo.dipperposition;
+import com.telpo.dipperposition.server.DipperPositionServer;
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 java.net.InetSocketAddress;
+
/**
* @program: gateway
* @description: 网关启动类
@@ -16,11 +20,17 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableConfigurationProperties
@EnableDiscoveryClient
@Slf4j
+@ConfigurationPropertiesScan
public class DipperPositionApplication {
public static void main(String[] args) {
log.info("北斗定位服务开始!");
SpringApplication.run(DipperPositionApplication.class, args);
log.info("北斗定位服务启动!");
+ //启动服务端
+ DipperPositionServer nettyServer = new DipperPositionServer();
+ nettyServer.startTimeAsnc();
+ nettyServer.startPosAsnc();
+ nettyServer.startStarsAsnc();
}
}
diff --git a/src/main/java/com/telpo/dipperposition/common/CSVUtil.java b/src/main/java/com/telpo/dipperposition/common/CSVUtil.java
new file mode 100644
index 0000000..e6d1ab0
--- /dev/null
+++ b/src/main/java/com/telpo/dipperposition/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/dipperposition/common/HexConvert.java b/src/main/java/com/telpo/dipperposition/common/HexConvert.java
new file mode 100644
index 0000000..8f79122
--- /dev/null
+++ b/src/main/java/com/telpo/dipperposition/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/dipperposition/common/OkHttpUtil.java b/src/main/java/com/telpo/dipperposition/common/OkHttpUtil.java
new file mode 100644
index 0000000..a31eb99
--- /dev/null
+++ b/src/main/java/com/telpo/dipperposition/common/OkHttpUtil.java
@@ -0,0 +1,155 @@
+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/dipperposition/common/RedisUtil.java b/src/main/java/com/telpo/dipperposition/common/RedisUtil.java
new file mode 100644
index 0000000..97933f0
--- /dev/null
+++ b/src/main/java/com/telpo/dipperposition/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