New file |
| | |
| | | # 此为注释– 将被Git 忽略 |
| | | # /结尾表示是目录,忽略目录和目录下的所有件 |
| | | # /开头表示根目录,否则是.gitignore的相对目录 |
| | | # !开头表示反选 |
| | | .idea/ |
| | | target/ |
| | | *.iml |
| | | *.ipr |
| | | *.iws |
| | | *.log |
| | | .svn/ |
| | | .project |
| | | rebel.xml |
| | | .rebel-remote.xml.* |
New file |
| | |
| | | The MIT License (MIT) |
| | | |
| | | Copyright (c) 2018 Xiong Neng |
| | | |
| | | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| | | this software and associated documentation files (the "Software"), to deal in |
| | | the Software without restriction, including without limitation the rights to |
| | | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
| | | the Software, and to permit persons to whom the Software is furnished to do so, |
| | | subject to the following conditions: |
| | | |
| | | The above copyright notice and this permission notice shall be included in all |
| | | copies or substantial portions of the Software. |
| | | |
| | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
| | | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
| | | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
| | | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| | | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | 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.xncoding</groupId> |
| | | <artifactId>HeartbeatServer</artifactId> |
| | | <version>1.0.0-RELEASE</version> |
| | | <packaging>jar</packaging> |
| | | |
| | | <name>HeartbeatServer</name> |
| | | <description>心跳检测</description> |
| | | |
| | | <parent> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-parent</artifactId> |
| | | <version>2.0.4.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> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter</artifactId> |
| | | </dependency> |
| | | <!-- https://mvnrepository.com/artifact/io.netty/netty-all --> |
| | | <dependency> |
| | | <groupId>io.netty</groupId> |
| | | <artifactId>netty-all</artifactId> |
| | | <version>4.1.73.Final</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.netty</groupId> |
| | | <artifactId>netty-handler</artifactId> |
| | | <version>4.1.72.Final</version> |
| | | </dependency> |
| | | <!-- hutool工具 --> |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-all</artifactId> |
| | | <version>5.7.20</version> |
| | | </dependency> |
| | | <!-- 阿里JSON解析器 --> |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>fastjson</artifactId> |
| | | <version>1.2.78</version> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | <build> |
| | | <plugins> |
| | | <plugin> |
| | | <groupId>org.apache.maven.plugins</groupId> |
| | | <artifactId>maven-compiler-plugin</artifactId> |
| | | <version>3.8.1</version> |
| | | <configuration> |
| | | <!--<proc>none</proc>--> |
| | | <source>1.8</source> |
| | | <target>1.8</target> |
| | | </configuration> |
| | | </plugin> |
| | | <plugin> |
| | | <groupId>org.apache.maven.plugins</groupId> |
| | | <artifactId>maven-surefire-plugin</artifactId> |
| | | <version>2.21.0</version> |
| | | <configuration> |
| | | <skip>true</skip> |
| | | </configuration> |
| | | </plugin> |
| | | <plugin> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-maven-plugin</artifactId> |
| | | <executions> |
| | | </executions> |
| | | </plugin> |
| | | </plugins> |
| | | |
| | | <resources> |
| | | <resource> |
| | | <directory>src/main/resources</directory> |
| | | </resource> |
| | | <resource> |
| | | <directory>src/main/java</directory> |
| | | <includes> |
| | | <include>**/*.xml</include> |
| | | </includes> |
| | | </resource> |
| | | </resources> |
| | | </build> |
| | | |
| | | </project> |
New file |
| | |
| | | #!/bin/bash |
| | | # 项目自动更新脚本 |
| | | # 先clone相应的分支下来: |
| | | # git clone ssh://git@120.24.173.142:7999/xxx.git |
| | | # 远程调试启动: |
| | | # nohup java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Xms512m -Xmx1024m -jar -Dspring.profiles.active=${profile} ${jarfile} >/dev/null 2>&1 & |
| | | |
| | | function start { |
| | | profile="$1" |
| | | echo "启动环境profile=${profile}" |
| | | jarfile=$(ls target/*.jar) |
| | | if [[ "$?" == "0" ]]; then |
| | | stop $profile $jarfile |
| | | fi |
| | | branch=$(git branch |awk '{print $2}') |
| | | git pull origin ${branch} |
| | | echo "更新完代码开始重新打包" |
| | | mvn clean && mvn clean && mvn package -DskipTests=true |
| | | if [[ "$?" != "0" ]]; then |
| | | echo "编译出错,退出!" |
| | | exit 1 |
| | | fi |
| | | echo "nohup java -Xms512m -Xmx1024m -jar -Dspring.profiles.active=${profile} ${jarfile} >/dev/null 2>&1 &" |
| | | nohup java -Xms512m -Xmx1024m -jar -Dspring.profiles.active=${profile} ${jarfile} >/dev/null 2>&1 & |
| | | echo "启动应用中,请查看日志文件..." |
| | | } |
| | | |
| | | function stop { |
| | | profile="$1" |
| | | jarfile="$2" |
| | | ps aux | grep "${jarfile}" | grep "spring.profiles.active=${profile}" | grep -v grep > /dev/null |
| | | if [[ "$?" == "0" ]]; then |
| | | echo "该应用还在跑,我先停了它" |
| | | pid=$(ps aux | grep "${jarfile}" | grep "spring.profiles.active=${profile}" | grep -v grep |awk '{print $2}') |
| | | if [[ "$pid" != "" ]]; then |
| | | kill -9 $pid |
| | | fi |
| | | echo "停止应用成功..." |
| | | fi |
| | | } |
| | | |
| | | if [[ "$1" == "start" ]]; then |
| | | if [[ "$#" < 2 ]]; then |
| | | echo "请输入正确参数:./epay.sh start {profile}" |
| | | exit 1 |
| | | fi |
| | | profile="$2" |
| | | if [[ "$profile" != "dev" && "$profile" != "test" && "$profile" != "show" && "$profile" != "production" ]]; then |
| | | echo "参数错误,请输入正确的profile参数,使用方法:" |
| | | echo "./epay.sh start {profile} ==> 启动应用,{profile}取值:dev|test|show|production" |
| | | exit 1 |
| | | fi |
| | | start "${profile}" |
| | | elif [[ "$1" == "stop" ]]; then |
| | | if [[ "$#" < 2 ]]; then |
| | | echo "请输入正确参数:./epay.sh stop {profile}" |
| | | exit 1 |
| | | fi |
| | | profile="$2" |
| | | if [[ "$profile" != "dev" && "$profile" != "test" && "$profile" != "show" && "$profile" != "production" ]]; then |
| | | echo "参数错误,请输入正确的profile参数,使用方法:" |
| | | echo "./epay.sh stop {profile} ==> 停止应用,{profile}取值:dev|test|show|production" |
| | | exit 1 |
| | | fi |
| | | jarfile=$(ls target/*.jar) |
| | | stop $profile $jarfile |
| | | else |
| | | echo "参数错误,使用方法:{}参数是必填的,[]参数可选" |
| | | echo "./epay.sh start {profile} ==> 启动应用,{profile}取值:dev|test|show|production" |
| | | echo "./epay.sh stop {profile} ==> 停止应用,{profile}取值:dev|test|show|production" |
| | | exit 1 |
| | | fi |
New file |
| | |
| | | package com.xncoding.pos; |
| | | |
| | | import com.xncoding.pos.handler.ClientStarter; |
| | | import io.netty.bootstrap.Bootstrap; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.boot.SpringApplication; |
| | | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| | | |
| | | @SpringBootApplication |
| | | public class Application { |
| | | private static final Logger logger = LoggerFactory.getLogger(Application.class); |
| | | |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(Application.class, args); |
| | | logger.info("启动执行连接服务"); |
| | | ClientStarter starter = new ClientStarter(new Bootstrap()); |
| | | starter.connect(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.xncoding.pos.config; |
| | | |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Component |
| | | @ConfigurationProperties("system.netty") |
| | | public class NettyProperties { |
| | | private int timeSeconds; |
| | | private String url; |
| | | private int port; |
| | | |
| | | public int getTimeSeconds() { |
| | | return timeSeconds; |
| | | } |
| | | |
| | | public void setTimeSeconds(int timeSeconds) { |
| | | this.timeSeconds = timeSeconds; |
| | | } |
| | | |
| | | public String getUrl() { |
| | | return url; |
| | | } |
| | | |
| | | public void setUrl(String url) { |
| | | this.url = url; |
| | | } |
| | | |
| | | public int getPort() { |
| | | return port; |
| | | } |
| | | |
| | | public void setPort(int port) { |
| | | this.port = port; |
| | | } |
| | | } |
New file |
| | |
| | | package com.xncoding.pos.config; |
| | | |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Component |
| | | @ConfigurationProperties("system.shell") |
| | | public class ShellProperties { |
| | | private int isRunShell; |
| | | private String url; |
| | | |
| | | public boolean isRunShell() { |
| | | return isRunShell == 0; |
| | | } |
| | | |
| | | public void setIsRunShell(int isRunShell) { |
| | | this.isRunShell = isRunShell; |
| | | } |
| | | |
| | | public String getUrl() { |
| | | return url; |
| | | } |
| | | |
| | | public void setUrl(String url) { |
| | | this.url = url; |
| | | } |
| | | } |
New file |
| | |
| | | package com.xncoding.pos.config; |
| | | |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Component |
| | | @ConfigurationProperties("system.sms") |
| | | public class SmsProperties { |
| | | private int isSendSms; |
| | | private String url; |
| | | private String userName; |
| | | private String pwd; |
| | | private String signature; |
| | | private String tpIdSuccess; |
| | | private String tpIdError; |
| | | private String mobiles; |
| | | |
| | | |
| | | public boolean isSendSms() { |
| | | return isSendSms == 0; |
| | | } |
| | | |
| | | public void setIsSendSms(int isSendSms) { |
| | | this.isSendSms = isSendSms; |
| | | } |
| | | |
| | | public String getUrl() { |
| | | return url; |
| | | } |
| | | |
| | | public void setUrl(String url) { |
| | | this.url = url; |
| | | } |
| | | |
| | | public String getUserName() { |
| | | return userName; |
| | | } |
| | | |
| | | public void setUserName(String userName) { |
| | | this.userName = userName; |
| | | } |
| | | |
| | | public String getPwd() { |
| | | return pwd; |
| | | } |
| | | |
| | | public void setPwd(String pwd) { |
| | | this.pwd = pwd; |
| | | } |
| | | |
| | | public String getSignature() { |
| | | return signature; |
| | | } |
| | | |
| | | public void setSignature(String signature) { |
| | | this.signature = signature; |
| | | } |
| | | |
| | | public String getTpIdSuccess() { |
| | | return tpIdSuccess; |
| | | } |
| | | |
| | | public void setTpIdSuccess(String tpIdSuccess) { |
| | | this.tpIdSuccess = tpIdSuccess; |
| | | } |
| | | |
| | | public String getTpIdError() { |
| | | return tpIdError; |
| | | } |
| | | |
| | | public void setTpIdError(String tpIdError) { |
| | | this.tpIdError = tpIdError; |
| | | } |
| | | |
| | | public String getMobiles() { |
| | | return mobiles; |
| | | } |
| | | |
| | | public void setMobiles(String mobiles) { |
| | | this.mobiles = mobiles; |
| | | } |
| | | } |
New file |
| | |
| | | package com.xncoding.pos.handler; |
| | | import java.net.InetSocketAddress; |
| | | |
| | | import com.xncoding.pos.config.NettyProperties; |
| | | import com.xncoding.pos.utils.ApplicationContextUtils; |
| | | import com.xncoding.pos.utils.RunShellUtils; |
| | | import com.xncoding.pos.utils.SmsUtils; |
| | | import io.netty.bootstrap.Bootstrap; |
| | | import io.netty.channel.ChannelFuture; |
| | | import io.netty.channel.ChannelInitializer; |
| | | import io.netty.channel.nio.NioEventLoopGroup; |
| | | import io.netty.channel.socket.SocketChannel; |
| | | import io.netty.channel.socket.nio.NioSocketChannel; |
| | | import io.netty.handler.codec.string.StringDecoder; |
| | | import io.netty.handler.codec.string.StringEncoder; |
| | | import io.netty.handler.timeout.IdleStateHandler; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | |
| | | |
| | | public class ClientStarter { |
| | | |
| | | private static final Logger logger = LoggerFactory.getLogger(ClientStarter.class); |
| | | |
| | | private static NettyProperties config; |
| | | |
| | | private final Bootstrap bootstrap; |
| | | |
| | | public ClientStarter(Bootstrap bootstrap) { |
| | | if(config == null){ |
| | | config = (NettyProperties)ApplicationContextUtils.getBean("nettyProperties"); |
| | | } |
| | | this.bootstrap = bootstrap; |
| | | ClientStarter clientStarter = this; |
| | | bootstrap.group(new NioEventLoopGroup()) |
| | | .channel(NioSocketChannel.class) |
| | | .handler(new ChannelInitializer<SocketChannel>() { |
| | | @Override |
| | | protected void initChannel(SocketChannel ch) throws Exception { |
| | | ch.pipeline().addLast(new StringEncoder()); |
| | | ch.pipeline().addLast(new StringDecoder()); |
| | | //发送消息频率。单位秒。此设置是5秒发送一次消息 |
| | | ch.pipeline().addLast(new IdleStateHandler(config.getTimeSeconds(), config.getTimeSeconds(), config.getTimeSeconds())); |
| | | ch.pipeline().addLast(new HeartBeatClientHandler(clientStarter)); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | public void connect() { |
| | | |
| | | ChannelFuture channelFuture = bootstrap.connect(new InetSocketAddress(config.getUrl(), config.getPort())); |
| | | channelFuture.addListener(future ->{ |
| | | if (future.isSuccess()) { |
| | | logger.info("连接服务成功"); |
| | | } else { |
| | | logger.info("服务ping失败"); |
| | | Thread.sleep(5000); |
| | | connect(); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | public static void main(String[] args) { |
| | | ClientStarter starter = new ClientStarter(new Bootstrap()); |
| | | starter.connect(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xncoding.pos.handler; |
| | | import java.io.IOException; |
| | | import java.util.Date; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | import com.xncoding.pos.utils.RunShellUtils; |
| | | import com.xncoding.pos.utils.SmsUtils; |
| | | import io.netty.channel.ChannelHandlerContext; |
| | | import io.netty.channel.EventLoop; |
| | | import io.netty.channel.SimpleChannelInboundHandler; |
| | | import io.netty.handler.timeout.IdleState; |
| | | import io.netty.handler.timeout.IdleStateEvent; |
| | | import io.netty.util.ReferenceCountUtil; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | |
| | | public class HeartBeatClientHandler extends SimpleChannelInboundHandler<String>{ |
| | | |
| | | |
| | | private final ClientStarter clientStarter; |
| | | private static final Logger logger = LoggerFactory.getLogger(HeartBeatClientHandler.class); |
| | | |
| | | public HeartBeatClientHandler(ClientStarter clientStarter) { |
| | | this.clientStarter = clientStarter; |
| | | } |
| | | |
| | | /** |
| | | * 客户端监听写事件。也就是设置时间内没有与服务端交互则发送ping 给服务端 |
| | | */ |
| | | @Override |
| | | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { |
| | | if(evt instanceof IdleStateEvent) { |
| | | IdleState state = ((IdleStateEvent)evt).state(); |
| | | if(state == IdleState.ALL_IDLE) { |
| | | ctx.writeAndFlush("PING"); |
| | | logger.info("PING SUCCESS"); |
| | | } |
| | | } |
| | | super.userEventTriggered(ctx, evt); |
| | | } |
| | | /** |
| | | * channelInactive 被触发一定是和服务器断开了。分两种情况。一种是服务端close,一种是客户端close。 |
| | | */ |
| | | @Override |
| | | public void channelInactive(ChannelHandlerContext ctx) { |
| | | try { |
| | | super.channelInactive(ctx); |
| | | logger.error("客户端与服务端断开连接,断开的时间为:"+(new Date()).toString()); |
| | | //1、重启服务 |
| | | RunShellUtils runShellUtils = new RunShellUtils(); |
| | | boolean runShell = runShellUtils.runShell(); |
| | | logger.info("runShell{}",runShell); |
| | | //2、 发送短信给系统维护人员 |
| | | SmsUtils smsUtils = new SmsUtils(); |
| | | smsUtils.sendSms(runShell); |
| | | //3、定时线程 断线重连 |
| | | final EventLoop eventLoop = ctx.channel().eventLoop(); |
| | | //设置断开连接后重连时间,此设置是断开连接分钟(120秒)后重连 |
| | | eventLoop.schedule(clientStarter::connect, 5, TimeUnit.SECONDS); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 在服务器端不使用心跳检测的情况下,如果客户端突然拔掉网线断网(注意这里不是客户度程序关闭,而仅是异常断网) |
| | | */ |
| | | @Override |
| | | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { |
| | | if(cause instanceof IOException) { |
| | | System.out.println("server "+ctx.channel().remoteAddress()+"关闭连接"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 消息监控,监听服务端传来的消息(和netty版本有关,有的版本这个方法叫做clientRead0) |
| | | */ |
| | | @Override |
| | | protected void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) throws Exception { |
| | | if ("PONG".equals(msg)) { |
| | | System.out.println("receive form server PONG"); |
| | | } |
| | | ReferenceCountUtil.release(msg); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xncoding.pos.utils; |
| | | |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationContextAware; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Component |
| | | public class ApplicationContextUtils implements ApplicationContextAware { |
| | | |
| | | private static ApplicationContext context; |
| | | |
| | | |
| | | @Override |
| | | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { |
| | | context = applicationContext; |
| | | } |
| | | |
| | | /** |
| | | * 获取bean |
| | | * @param beanName |
| | | * @return |
| | | */ |
| | | public static Object getBean(String beanName) { |
| | | return context.getBean(beanName); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xncoding.pos.utils; |
| | | |
| | | import com.xncoding.pos.config.ShellProperties; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.io.InputStreamReader; |
| | | import java.io.LineNumberReader; |
| | | |
| | | public class RunShellUtils { |
| | | private static final Logger logger = LoggerFactory.getLogger(RunShellUtils.class); |
| | | private static ShellProperties shellProperties; |
| | | public RunShellUtils(){ |
| | | if (shellProperties == null){ |
| | | shellProperties = (ShellProperties)ApplicationContextUtils.getBean("shellProperties"); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 执行shell |
| | | * @return 默认执行成功 true 执行成功 false 执行失败 |
| | | */ |
| | | public boolean runShell(){ |
| | | //默认执行成功 |
| | | boolean b = true; |
| | | if (shellProperties.isRunShell()) { |
| | | try { |
| | | // 1、重启脚本执行 |
| | | exec(shellProperties.getUrl()); |
| | | logger.info("重启脚本执行成功!"); |
| | | // // 2、执行启动脚本 |
| | | // exec(shellProperties.getRunUrl()); |
| | | // logger.info("启动脚本执行成功!"); |
| | | }catch (Exception e){ |
| | | logger.error("脚本执行失败!"); |
| | | b = false; |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | return b; |
| | | } |
| | | |
| | | private void rumShell(String url) throws Exception { |
| | | Process ps = Runtime.getRuntime().exec(url); |
| | | ps.waitFor(); |
| | | } |
| | | |
| | | |
| | | private void exec(String cmd) { |
| | | try { |
| | | logger.info("cmd:{}",cmd); |
| | | String[] cmdA = { "/bin/sh", "-c", cmd }; |
| | | Process process = Runtime.getRuntime().exec(cmdA); |
| | | LineNumberReader br = new LineNumberReader(new InputStreamReader( |
| | | process.getInputStream())); |
| | | StringBuffer sb = new StringBuffer(); |
| | | String line; |
| | | while ((line = br.readLine()) != null) { |
| | | logger.info(line); |
| | | sb.append(line).append("\n"); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.xncoding.pos.utils; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.crypto.SecureUtil; |
| | | import cn.hutool.http.HttpRequest; |
| | | import com.xncoding.pos.config.ShellProperties; |
| | | import com.xncoding.pos.config.SmsProperties; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | |
| | | /** |
| | | * 短信服务 |
| | | */ |
| | | public class SmsUtils { |
| | | private static final Logger logger = LoggerFactory.getLogger(SmsUtils.class); |
| | | private static SmsProperties smsProperties; |
| | | |
| | | public SmsUtils() { |
| | | if (smsProperties == null){ |
| | | smsProperties = (SmsProperties)ApplicationContextUtils.getBean("smsProperties"); |
| | | } |
| | | } |
| | | |
| | | public void sendSms( boolean isSuccess) { |
| | | logger.info("是否发送短信{}",smsProperties.isSendSms()); |
| | | if(!smsProperties.isSendSms()){return;} |
| | | //请求入参 |
| | | JSONObject requestJson = new JSONObject(); |
| | | //账号 |
| | | requestJson.put("username", smsProperties.getUserName()); |
| | | //tKey |
| | | long tKey = System.currentTimeMillis() / 1000; |
| | | requestJson.put("tKey", tKey); |
| | | //明文密码 |
| | | requestJson.put("password", SecureUtil.md5(SecureUtil.md5(smsProperties.getPwd()) + tKey)); |
| | | //模板ID |
| | | requestJson.put("tpId",isSuccess? smsProperties.getTpIdSuccess():smsProperties.getTpIdError()); |
| | | //签名 |
| | | requestJson.put("signature", smsProperties.getSignature()); |
| | | //扩展号 |
| | | requestJson.put("ext", ""); |
| | | //自定义参数 |
| | | requestJson.put("extend", ""); |
| | | //发送记录集合 |
| | | JSONArray records = new JSONArray(); |
| | | JSONObject record = new JSONObject(); |
| | | |
| | | String[] split = smsProperties.getMobiles().split(";"); |
| | | String now = DateUtil.now(); |
| | | for (String mobile : split) { |
| | | //手机号 |
| | | record.put("mobile", mobile); |
| | | //替换变量 |
| | | JSONObject param = new JSONObject(); |
| | | param.put("date",now); |
| | | record.put("tpContent", param); |
| | | records.add(record); |
| | | |
| | | } |
| | | requestJson.put("records", records); |
| | | logger.info("短信请求:{}", requestJson); |
| | | String result = HttpRequest.post(smsProperties.getUrl()) |
| | | .timeout(60000) |
| | | .body(requestJson.toJSONString(),"application/json;charset=UTF-8").execute().body(); |
| | | logger.info("短信返回:{}", result); |
| | | |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | spring: |
| | | profiles: |
| | | active: dev |
| | | # 开发环境配置 |
| | | server: |
| | | # 服务器的Http端口,默认为8090 |
| | | port: 8090 |
| | | servlet: |
| | | #应用的访问路径 |
| | | context-path: / |
| | | |
| | | logging: |
| | | level: |
| | | ROOT: INFO |
| | | com: |
| | | xncoding: DEBUG |
| | | file: /root/PubSvc/Logs/PubSvcAPI/HeartbeatServer.log |
| | | |
| | | system: |
| | | # 短信 |
| | | sms: |
| | | # 是否发送短信 0 发送 1不发送 |
| | | isSendSms: 1 |
| | | # 短信地址 |
| | | url: https://101.132.90.14/v2/sendSmsTp |
| | | # 短信账户 |
| | | userName: gdghhy |
| | | # 短信密码 |
| | | pwd: Gdgh1234 |
| | | # 公司名称 |
| | | signature: 【广东冠汇信息科技有限公司】 |
| | | # 脚本执行成功模版Id |
| | | tpIdSuccess: 48319 |
| | | # 脚本执行失败模版Id |
| | | tpIdError: 48327 |
| | | # 发送到目标手机号 可以多个以;分割 |
| | | mobiles: "13510693034;15815213711;18520822537" |
| | | #mobiles: "15815213711;" |
| | | netty: |
| | | # 心跳目标服务地址 |
| | | #url: '127.0.0.1' |
| | | url: '172.17.0.1' |
| | | # 心跳目标服务端口 |
| | | #port: 7001 |
| | | port: 7000 |
| | | # 心跳检测时间间隔 |
| | | time-seconds: 5 |
| | | shell: |
| | | # 是否启动自动执行脚本 0 执行 1不执行 |
| | | isRunShell: 0 |
| | | # 脚本 |
| | | url: 'sh /root/PubSvc/Bin/restart-base.sh' |