@@ -0,0 +1,2 @@ | |||
# Default ignored files | |||
/workspace.xml |
@@ -0,0 +1,9 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<module type="JAVA_MODULE" version="4"> | |||
<component name="NewModuleRootManager" inherit-compiler-output="true"> | |||
<exclude-output /> | |||
<content url="file://$MODULE_DIR$" /> | |||
<orderEntry type="inheritedJdk" /> | |||
<orderEntry type="sourceFolder" forTests="false" /> | |||
</component> | |||
</module> |
@@ -0,0 +1,6 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="GoogleJavaFormatSettings"> | |||
<option name="enabled" value="false" /> | |||
</component> | |||
</project> |
@@ -0,0 +1,36 @@ | |||
<component name="InspectionProjectProfileManager"> | |||
<profile version="1.0"> | |||
<option name="myName" value="Project Default" /> | |||
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true"> | |||
<option name="TOP_LEVEL_CLASS_OPTIONS"> | |||
<value> | |||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> | |||
<option name="REQUIRED_TAGS" value="" /> | |||
</value> | |||
</option> | |||
<option name="INNER_CLASS_OPTIONS"> | |||
<value> | |||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> | |||
<option name="REQUIRED_TAGS" value="" /> | |||
</value> | |||
</option> | |||
<option name="METHOD_OPTIONS"> | |||
<value> | |||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> | |||
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" /> | |||
</value> | |||
</option> | |||
<option name="FIELD_OPTIONS"> | |||
<value> | |||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" /> | |||
<option name="REQUIRED_TAGS" value="" /> | |||
</value> | |||
</option> | |||
<option name="IGNORE_DEPRECATED" value="false" /> | |||
<option name="IGNORE_JAVADOC_PERIOD" value="true" /> | |||
<option name="IGNORE_DUPLICATED_THROWS" value="false" /> | |||
<option name="IGNORE_POINT_TO_ITSELF" value="false" /> | |||
<option name="myAdditionalJavadocTags" value="date" /> | |||
</inspection_tool> | |||
</profile> | |||
</component> |
@@ -0,0 +1,6 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="JavaScriptSettings"> | |||
<option name="languageLevel" value="ES6" /> | |||
</component> | |||
</project> |
@@ -0,0 +1,8 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="ProjectModuleManager"> | |||
<modules> | |||
<module fileurl="file://$PROJECT_DIR$/.idea/BeidouAstPos.iml" filepath="$PROJECT_DIR$/.idea/BeidouAstPos.iml" /> | |||
</modules> | |||
</component> | |||
</project> |
@@ -0,0 +1,6 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="VcsDirectoryMappings"> | |||
<mapping directory="" vcs="Git" /> | |||
</component> | |||
</project> |
@@ -0,0 +1,148 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xmlns="http://maven.apache.org/POM/4.0.0" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<groupId>com.telpo</groupId> | |||
<artifactId>beidouast</artifactId> | |||
<version>1.0-SNAPSHOT</version> | |||
<name>beidouast</name> | |||
<description>北斗定位服务</description> | |||
<packaging>jar</packaging> | |||
<parent> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-parent</artifactId> | |||
<version>2.2.5.RELEASE</version> | |||
</parent> | |||
<properties> | |||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||
<java.version>1.8</java.version> | |||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding> | |||
<spring-cloud-alibaba.version>2.2.0.RELEASE</spring-cloud-alibaba.version> | |||
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version> | |||
<skipTests>true</skipTests> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-devtools</artifactId> | |||
<scope>runtime</scope> | |||
<optional>true</optional> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<optional>true</optional> | |||
</dependency> | |||
<!--天波通用包--> | |||
<dependency> | |||
<groupId>com.telpo</groupId> | |||
<artifactId>common</artifactId> | |||
<version>1.1.19</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-webflux</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-configuration-processor</artifactId> | |||
<optional>true</optional> | |||
</dependency> | |||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> | |||
<dependency> | |||
<groupId>org.apache.commons</groupId> | |||
<artifactId>commons-lang3</artifactId> | |||
<version>3.10</version> | |||
</dependency> | |||
<!-- Yaml --> | |||
<dependency> | |||
<groupId>org.yaml</groupId> | |||
<artifactId>snakeyaml</artifactId> | |||
<version>1.25</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.alibaba</groupId> | |||
<artifactId>fastjson</artifactId> | |||
<version>1.2.28</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>io.netty</groupId> | |||
<artifactId>netty-all</artifactId> | |||
<version>4.1.13.Final</version> | |||
</dependency> | |||
<!-- 开启redis缓存 --> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-starter-data-redis</artifactId> | |||
</dependency> | |||
<!-- redis依赖commons-pool 这个依赖一定要添加 --> | |||
<dependency> | |||
<groupId>org.apache.commons</groupId> | |||
<artifactId>commons-pool2</artifactId> | |||
</dependency> | |||
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp --> | |||
<dependency> | |||
<groupId>com.squareup.okhttp3</groupId> | |||
<artifactId>okhttp</artifactId> | |||
<version>4.8.0</version> | |||
</dependency> | |||
<!-- https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-client --> | |||
<dependency> | |||
<groupId>de.codecentric</groupId> | |||
<artifactId>spring-boot-admin-starter-client</artifactId> | |||
<version>2.2.4</version> | |||
</dependency> | |||
<!-- https://mvnrepository.com/artifact/net.sourceforge.javacsv/javacsv --> | |||
<dependency> | |||
<groupId>net.sourceforge.javacsv</groupId> | |||
<artifactId>javacsv</artifactId> | |||
<version>2.0</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.mongodb</groupId> | |||
<artifactId>mongo</artifactId> | |||
<version>1.0</version> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<finalName>${project.artifactId}</finalName> | |||
<plugins> | |||
<plugin> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-maven-plugin</artifactId> | |||
<configuration> | |||
<!--fork : 使用 devtools生效--> | |||
<fork>true</fork> | |||
</configuration> | |||
<executions> | |||
<execution> | |||
<goals> | |||
<goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中--> | |||
</goals> | |||
</execution> | |||
</executions> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
</project> |
@@ -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启动=======================' |
@@ -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()); | |||
} | |||
} | |||
} |
@@ -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 ""; | |||
} |
@@ -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; | |||
} |
@@ -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<String> readCSV(String readPath) { | |||
String filePath = readPath; | |||
List<String> 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(); | |||
} | |||
} | |||
} | |||
} |
@@ -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<hex.length()-1; i+=2 ){ | |||
String s = hex.substring(i, (i + 2)); | |||
int decimal = Integer.parseInt(s, 16); | |||
sb.append((char)decimal); | |||
sb2.append(decimal); | |||
} | |||
return sb.toString(); | |||
} | |||
public static byte[] hexStringToBytes(String hexString) { | |||
if (hexString == null || hexString.equals("")) { | |||
return null; | |||
} | |||
// toUpperCase将字符串中的所有字符转换为大写 | |||
hexString = hexString.toUpperCase(); | |||
int length = hexString.length() / 2; | |||
// toCharArray将此字符串转换为一个新的字符数组。 | |||
char[] hexChars = hexString.toCharArray(); | |||
byte[] d = new byte[length]; | |||
for (int i = 0; i < length; i++) { | |||
int pos = i * 2; | |||
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); | |||
} | |||
return d; | |||
} | |||
//返回匹配字符 | |||
private static byte charToByte(char c) { | |||
return (byte) "0123456789ABCDEF".indexOf(c); | |||
} | |||
//将字节数组转换为short类型,即统计字符串长度 | |||
public static short bytes2Short2(byte[] b) { | |||
short i = (short) (((b[1] & 0xff) << 8) | b[0] & 0xff); | |||
return i; | |||
} | |||
//将字节数组转换为16进制字符串 | |||
public static String BinaryToHexString(byte[] bytes) { | |||
String hexStr = "0123456789ABCDEF"; | |||
String result = ""; | |||
String hex = ""; | |||
for (byte b : bytes) { | |||
hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 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 )); | |||
// } | |||
} |
@@ -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<String, String> 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<String, String>) 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<String, String> 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<String, String> 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); | |||
} | |||
} | |||
} | |||
} |
@@ -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<String, Object> 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<Object, Object> hmget(String key) { | |||
return redisTemplate.opsForHash().entries(key); | |||
} | |||
/** | |||
* HashSet | |||
* | |||
* @param key 键 | |||
* @param map 对应多个键值 | |||
* @return true 成功 false 失败 | |||
*/ | |||
public boolean hmset(String key, Map<String, Object> 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<String, Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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; | |||
} | |||
} | |||
} |
@@ -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()); | |||
} | |||
} | |||
} |
@@ -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()); | |||
}; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
// } | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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<String, MongoDbFactory> MONGO_CLIENT_DB_FACTORY_MAP = new HashMap<>(); | |||
private static final ThreadLocal<MongoDbFactory> 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<MongoDbFactory> iterator = MONGO_CLIENT_DB_FACTORY_MAP.values().iterator(); | |||
return new MultiMongoTemplate(iterator.next()); | |||
} | |||
@Bean(name = "mongoDbFactory") | |||
public MongoDbFactory mongoDbFactory() { | |||
Iterator<MongoDbFactory> iterator = MONGO_CLIENT_DB_FACTORY_MAP.values().iterator(); | |||
return iterator.next(); | |||
} | |||
} |
@@ -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<MongoList> dblist; | |||
@Data | |||
public static class MongoList { | |||
private String uri; | |||
private String database; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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<SocketChannel> { | |||
@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()); | |||
} | |||
} |
@@ -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<IPProvinceEntity> { | |||
@Override | |||
protected Class<IPProvinceEntity> 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<IPProvinceEntity> getPage(IPProvinceEntity object, int start, int size) { | |||
return super.getPage(object, start, size); | |||
} | |||
@Override | |||
@MongoSwitch("common") | |||
public List<IPProvinceEntity> queryList(IPProvinceEntity object) { | |||
return super.queryList(object); | |||
} | |||
@Override | |||
@MongoSwitch("common") | |||
public List<IPProvinceEntity> queryList(IPProvinceEntity object, String collectionName) { | |||
return super.queryList(object, collectionName); | |||
} | |||
@Override | |||
@MongoSwitch("common") | |||
public void deleteById(String id) { | |||
super.deleteById(id); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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(); | |||
} |
@@ -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(); | |||
} |
@@ -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); | |||
} |
@@ -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<String> 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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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<IPProvinceEntity> pushRecords = iPProvinceMapper.queryList(query); | |||
if (ObjectUtils.isNotEmpty(pushRecords)) { | |||
return pushRecords.get(0); | |||
} else { | |||
return null; | |||
} | |||
} catch (Exception e) { | |||
log.error("获取IP省份异常:", e); | |||
return null; | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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 |
@@ -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,澳门特别行政区 |
@@ -0,0 +1,198 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --> | |||
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true --> | |||
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 --> | |||
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --> | |||
<configuration scan="true" scanPeriod="10 seconds"> | |||
<!--<include resource="org/springframework/boot/logging/logback/base.xml" />--> | |||
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --> | |||
<!-- property name="log.path" value="/var/log/dipperposition"/ --> | |||
<property name="log.path" value="/home/data/dipperposition"/> | |||
<!-- 彩色日志 --> | |||
<!-- 彩色日志依赖的渲染类 --> | |||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/> | |||
<conversionRule conversionWord="wex" | |||
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/> | |||
<conversionRule conversionWord="wEx" | |||
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/> | |||
<!-- 彩色日志格式 --> | |||
<property name="CONSOLE_LOG_PATTERN" | |||
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> | |||
<!--输出到控制台--> | |||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> | |||
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--> | |||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> | |||
<level>debug</level> | |||
</filter> | |||
<encoder> | |||
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern> | |||
<!-- 设置字符集 --> | |||
<charset>UTF-8</charset> | |||
</encoder> | |||
</appender> | |||
<!--输出到文件--> | |||
<!-- 时间滚动输出 level为 DEBUG 日志 --> | |||
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||
<!-- 正在记录的日志文件的路径及文件名 --> | |||
<file>${log.path}/log_debug.log</file> | |||
<!--日志文件输出格式--> | |||
<encoder> | |||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> | |||
<charset>UTF-8</charset> <!-- 设置字符集 --> | |||
</encoder> | |||
<!-- 日志记录器的滚动策略,按日期,按大小记录 --> | |||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||
<!-- 日志归档 --> | |||
<fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern> | |||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> | |||
<maxFileSize>100MB</maxFileSize> | |||
</timeBasedFileNamingAndTriggeringPolicy> | |||
<!--日志文件保留天数--> | |||
<maxHistory>15</maxHistory> | |||
</rollingPolicy> | |||
<!-- 此日志文件只记录debug级别的 --> | |||
<filter class="ch.qos.logback.classic.filter.LevelFilter"> | |||
<level>debug</level> | |||
<onMatch>ACCEPT</onMatch> | |||
<onMismatch>DENY</onMismatch> | |||
</filter> | |||
</appender> | |||
<!-- 时间滚动输出 level为 INFO 日志 --> | |||
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||
<!-- 正在记录的日志文件的路径及文件名 --> | |||
<file>${log.path}/log_info.log</file> | |||
<!--日志文件输出格式--> | |||
<encoder> | |||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> | |||
<charset>UTF-8</charset> | |||
</encoder> | |||
<!-- 日志记录器的滚动策略,按日期,按大小记录 --> | |||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||
<!-- 每天日志归档路径以及格式 --> | |||
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> | |||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> | |||
<maxFileSize>100MB</maxFileSize> | |||
</timeBasedFileNamingAndTriggeringPolicy> | |||
<!--日志文件保留天数--> | |||
<maxHistory>15</maxHistory> | |||
</rollingPolicy> | |||
<!-- 此日志文件只记录info级别的 --> | |||
<filter class="ch.qos.logback.classic.filter.LevelFilter"> | |||
<level>info</level> | |||
<onMatch>ACCEPT</onMatch> | |||
<onMismatch>DENY</onMismatch> | |||
</filter> | |||
</appender> | |||
<!-- 时间滚动输出 level为 WARN 日志 --> | |||
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||
<!-- 正在记录的日志文件的路径及文件名 --> | |||
<file>${log.path}/log_warn.log</file> | |||
<!--日志文件输出格式--> | |||
<encoder> | |||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> | |||
<charset>UTF-8</charset> <!-- 此处设置字符集 --> | |||
</encoder> | |||
<!-- 日志记录器的滚动策略,按日期,按大小记录 --> | |||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||
<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> | |||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> | |||
<maxFileSize>100MB</maxFileSize> | |||
</timeBasedFileNamingAndTriggeringPolicy> | |||
<!--日志文件保留天数--> | |||
<maxHistory>15</maxHistory> | |||
</rollingPolicy> | |||
<!-- 此日志文件只记录warn级别的 --> | |||
<filter class="ch.qos.logback.classic.filter.LevelFilter"> | |||
<level>warn</level> | |||
<onMatch>ACCEPT</onMatch> | |||
<onMismatch>DENY</onMismatch> | |||
</filter> | |||
</appender> | |||
<!-- 时间滚动输出 level为 ERROR 日志 --> | |||
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||
<!-- 正在记录的日志文件的路径及文件名 --> | |||
<file>${log.path}/log_error.log</file> | |||
<!--日志文件输出格式--> | |||
<encoder> | |||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> | |||
<charset>UTF-8</charset> <!-- 此处设置字符集 --> | |||
</encoder> | |||
<!-- 日志记录器的滚动策略,按日期,按大小记录 --> | |||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||
<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> | |||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> | |||
<maxFileSize>100MB</maxFileSize> | |||
</timeBasedFileNamingAndTriggeringPolicy> | |||
<!--日志文件保留天数--> | |||
<maxHistory>15</maxHistory> | |||
</rollingPolicy> | |||
<!-- 此日志文件只记录ERROR级别的 --> | |||
<filter class="ch.qos.logback.classic.filter.LevelFilter"> | |||
<level>ERROR</level> | |||
<onMatch>ACCEPT</onMatch> | |||
<onMismatch>DENY</onMismatch> | |||
</filter> | |||
</appender> | |||
<!-- | |||
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、 | |||
以及指定<appender>。<logger>仅有一个name属性, | |||
一个可选的level和一个可选的addtivity属性。 | |||
name:用来指定受此logger约束的某一个包或者具体的某一个类。 | |||
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, | |||
还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。 | |||
如果未设置此属性,那么当前logger将会继承上级的级别。 | |||
addtivity:是否向上级logger传递打印信息。默认是true。 | |||
--> | |||
<!--<logger name="org.springframework.web" level="info"/>--> | |||
<!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>--> | |||
<!-- | |||
使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作: | |||
第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息 | |||
第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别: | |||
--> | |||
<!-- | |||
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性 | |||
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, | |||
不能设置为INHERITED或者同义词NULL。默认是DEBUG | |||
可以包含零个或多个元素,标识这个appender将会添加到这个logger。 | |||
--> | |||
<!--开发环境:打印控制台--> | |||
<springProfile name="dev"> | |||
<logger name="com.telpo.dipperposition" level="debug"/> | |||
</springProfile> | |||
<root level="info"> | |||
<appender-ref ref="CONSOLE"/> | |||
<appender-ref ref="DEBUG_FILE"/> | |||
<appender-ref ref="INFO_FILE"/> | |||
<appender-ref ref="WARN_FILE"/> | |||
<appender-ref ref="ERROR_FILE"/> | |||
</root> | |||
<!--生产环境:输出到文件--> | |||
<!--<springProfile name="pro">--> | |||
<!--<root level="info">--> | |||
<!--<appender-ref ref="CONSOLE" />--> | |||
<!--<appender-ref ref="DEBUG_FILE" />--> | |||
<!--<appender-ref ref="INFO_FILE" />--> | |||
<!--<appender-ref ref="ERROR_FILE" />--> | |||
<!--<appender-ref ref="WARN_FILE" />--> | |||
<!--</root>--> | |||
<!--</springProfile>--> | |||
</configuration> |