From 22c308a8c1317473c7279f7bf866814c64ef36e9 Mon Sep 17 00:00:00 2001 From: Pu Zhibing <393733352@qq.com> Date: 星期日, 22 六月 2025 01:09:54 +0800 Subject: [PATCH] 提交推送服务 --- MessagePushTravel/src/main/java/com/sinata/push/controller/NettyController.java | 10 MessagePushTravel/src/main/java/com/sinata/push/util/echo/ServerInit.java | 2 MessagePushTravel/src/main/java/com/sinata/push/util/applets/NettyWebSocketController.java | 198 +++++++++++++ MessagePushTravel/src/main/java/com/sinata/push/util/applets/ChildChannelHandler.java | 25 + MessagePushTravel/src/main/java/com/sinata/push/util/applets/ClientPingMessage.java | 2 MessagePushTravel/src/main/resources/application.yml | 39 ++ MessagePushTravel/src/main/java/com/sinata/push/util/NettyStartListener.java | 15 MessagePushTravel/src/main/java/com/sinata/push/util/applets/WebSocketHandler.java | 10 MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyChannelMap.java | 19 - MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyServerController.java | 170 ++++++----- MessagePushTravel/src/main/java/com/sinata/push/util/echo/Method.java | 5 MessagePushTravel/src/main/java/com/sinata/push/util/URLUtil.java | 12 MessagePushTravel/src/main/java/com/sinata/push/util/applets/CacheType.java | 2 MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyMsg.java | 2 MessagePushTravel/src/main/java/com/sinata/push/util/StringUtil.java | 35 -- MessagePushTravel/src/main/java/com/sinata/push/util/ResultUtil.java | 8 MessagePushTravel/src/main/java/com/sinata/push/util/applets/Global.java | 2 MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyServer.java | 6 MessagePushTravel/src/main/java/com/sinata/push/util/SpringUtil.java | 2 MessagePushTravel/src/main/resources/static/tXQaRbVjpJ.txt | 0 MessagePushTravel/src/main/java/com/sinata/push/util/echo/DiscardServerHandler.java | 4 MessagePushTravel/pom.xml | 83 +++++ MessagePushTravel/src/main/java/com/sinata/push/util/applets/createSSLContext.java | 2 MessagePushTravel/src/main/java/com/sinata/push/MessagePushApplication.java | 19 + MessagePushTravel/src/main/java/com/sinata/push/util/applets/NettyServer0.java | 4 MessagePushTravel/src/main/resources/logback.xml | 222 ++++++++++++++ MessagePushTravel/src/main/java/com/sinata/push/util/SinataUtil.java | 2 27 files changed, 719 insertions(+), 181 deletions(-) diff --git a/MessagePushTravel/pom.xml b/MessagePushTravel/pom.xml new file mode 100644 index 0000000..7ccc743 --- /dev/null +++ b/MessagePushTravel/pom.xml @@ -0,0 +1,83 @@ +<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-parent</artifactId> + <version>2.0.4.RELEASE</version> + <relativePath/> <!-- lookup parent from repository --> + </parent> + <groupId>com.sinata</groupId> + <artifactId>message</artifactId> + <version>1.0.0</version> + <name>message</name> + <description>message-push project for Spring Boot</description> + + <packaging>jar</packaging> + + <properties> + <java.version>1.8</java.version> + <spring-cloud.version>Finchley.SR1</spring-cloud.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-redis</artifactId> + </dependency> + <!-- netty --> + <dependency> + <groupId>io.netty</groupId> + <artifactId>netty-all</artifactId> + <version>4.1.27.Final</version> + </dependency> + <dependency> + <groupId>com.alibaba</groupId> + <artifactId>fastjson</artifactId> + <version>1.2.47</version> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>cn.hutool</groupId> + <artifactId>hutool-all</artifactId> + <version>5.8.25</version> + </dependency> + </dependencies> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-dependencies</artifactId> + <version>${spring-cloud.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + </plugin> + </plugins> + </build> + +</project> diff --git a/MessagePushTravel/src/main/java/com/sinata/push/MessagePushApplication.java b/MessagePushTravel/src/main/java/com/sinata/push/MessagePushApplication.java new file mode 100644 index 0000000..707c4a3 --- /dev/null +++ b/MessagePushTravel/src/main/java/com/sinata/push/MessagePushApplication.java @@ -0,0 +1,19 @@ +package com.sinata.push; + +import com.sinata.push.util.applets.NettyServer0; +import com.sinata.push.util.echo.NettyServer; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MessagePushApplication { + + public static void main(String[] args) { + SpringApplication.run(MessagePushApplication.class, args); + NettyServer nettyServer = new NettyServer(); + nettyServer.bind(); + NettyServer0 nettyServer0 = new NettyServer0(); + nettyServer0.bind(); + } + +} diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/controller/NettyController.java b/MessagePushTravel/src/main/java/com/sinata/push/controller/NettyController.java similarity index 87% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/controller/NettyController.java rename to MessagePushTravel/src/main/java/com/sinata/push/controller/NettyController.java index b34e425..178936d 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/controller/NettyController.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/controller/NettyController.java @@ -1,11 +1,11 @@ -package com.sinata.zuul.controller; +package com.sinata.push.controller; import com.alibaba.fastjson.JSON; -import com.sinata.zuul.util.ResultUtil; -import com.sinata.zuul.util.applets.NettyWebSocketController; -import com.sinata.zuul.util.echo.NettyChannelMap; -import com.sinata.zuul.util.echo.NettyServerController; +import com.sinata.push.util.ResultUtil; +import com.sinata.push.util.applets.NettyWebSocketController; +import com.sinata.push.util.echo.NettyChannelMap; +import com.sinata.push.util.echo.NettyServerController; import io.netty.channel.ChannelHandlerContext; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/NettyStartListener.java b/MessagePushTravel/src/main/java/com/sinata/push/util/NettyStartListener.java similarity index 63% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/NettyStartListener.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/NettyStartListener.java index 2f19e93..92805f0 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/NettyStartListener.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/NettyStartListener.java @@ -1,7 +1,4 @@ -package com.sinata.zuul.util; - -import com.sinata.zuul.util.applets.NettyServer0; -import com.sinata.zuul.util.echo.NettyServer; +package com.sinata.push.util; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @@ -19,11 +16,11 @@ Thread thread = new Thread(new Runnable() { @Override public void run() { - NettyServer nettyServer = new NettyServer(); - nettyServer.bind(); - - NettyServer0 nettyServer0 = new NettyServer0(); - nettyServer0.bind(); +// NettyServer nettyServer = new NettyServer(); +// nettyServer.bind(); +// +// NettyServer0 nettyServer0 = new NettyServer0(); +// nettyServer0.bind(); } }); thread.start(); diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/ResultUtil.java b/MessagePushTravel/src/main/java/com/sinata/push/util/ResultUtil.java similarity index 88% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/ResultUtil.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/ResultUtil.java index 5a4f428..618c2c2 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/ResultUtil.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/ResultUtil.java @@ -1,13 +1,10 @@ -package com.sinata.zuul.util; +package com.sinata.push.util; import com.alibaba.fastjson.JSONObject; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; /** * 定义统一返回对象 */ -@ApiModel(value = "统一返回结果集") public class ResultUtil<T> { public static final Integer SUCCESS = 200; @@ -26,13 +23,10 @@ public static final String SIGN = "SIGN_INVALID"; - @ApiModelProperty(name = "code", value = "业务状态码 200:成功,300:参数错误,400:运行异常,500:其他异常, 600:token无效,需重新登录,700:签名无效") private Integer code;//备用状态码 - @ApiModelProperty(name = "msg", value = "返回结果说明") private String msg;//返回说明 - @ApiModelProperty(name = "data", value = "返回结果值") private T data;//返回数据 diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/SinataUtil.java b/MessagePushTravel/src/main/java/com/sinata/push/util/SinataUtil.java similarity index 99% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/SinataUtil.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/SinataUtil.java index 287d4ad..7dd55f5 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/SinataUtil.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/SinataUtil.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util; +package com.sinata.push.util; import java.io.UnsupportedEncodingException; import java.text.DecimalFormat; diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/SpringUtil.java b/MessagePushTravel/src/main/java/com/sinata/push/util/SpringUtil.java similarity index 96% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/SpringUtil.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/SpringUtil.java index 838138a..c4566c9 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/SpringUtil.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/SpringUtil.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util; +package com.sinata.push.util; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/StringUtil.java b/MessagePushTravel/src/main/java/com/sinata/push/util/StringUtil.java similarity index 73% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/StringUtil.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/StringUtil.java index 3f6641f..48091f6 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/StringUtil.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/StringUtil.java @@ -1,6 +1,6 @@ -package com.sinata.zuul.util; +package com.sinata.push.util; -import org.apache.commons.lang.StringUtils; + public class StringUtil { @@ -65,37 +65,6 @@ } - /** - * 过滤掉字符串中的表情 - * @param source - * @return - */ - public static String filterEmoji(String source) { - if (StringUtils.isBlank(source)) { - return source; - } - StringBuilder buf = null; - int len = source.length(); - for (int i = 0; i < len; i++) { - char codePoint = source.charAt(i); - if (isEmojiCharacter(codePoint)) { - if (buf == null) { - buf = new StringBuilder(source.length()); - } - buf.append(codePoint); - } - } - if (buf == null) { - return source; - } else { - if (buf.length() == len) { - buf = null; - return source; - } else { - return buf.toString(); - } - } - } /** diff --git a/MessagePushTravel/src/main/java/com/sinata/push/util/URLUtil.java b/MessagePushTravel/src/main/java/com/sinata/push/util/URLUtil.java new file mode 100644 index 0000000..e210b25 --- /dev/null +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/URLUtil.java @@ -0,0 +1,12 @@ +package com.sinata.push.util; + +/** + * @author zhibing.pu + * @Date 2025/6/22 0:33 + */ +public interface URLUtil { + /** + * 业务网关接口地址 + */ + String zuul = "http://172.21.35.45:80"; +} diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/CacheType.java b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/CacheType.java similarity index 97% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/CacheType.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/applets/CacheType.java index 65621d6..938d02a 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/CacheType.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/CacheType.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util.applets; +package com.sinata.push.util.applets; /** * 缓存消息类型 diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/ChildChannelHandler.java b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/ChildChannelHandler.java similarity index 62% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/ChildChannelHandler.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/applets/ChildChannelHandler.java index edbbae5..5072004 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/ChildChannelHandler.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/ChildChannelHandler.java @@ -1,26 +1,37 @@ -package com.sinata.zuul.util.applets; +package com.sinata.push.util.applets; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; +import io.netty.handler.ssl.ClientAuth; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslHandler; +import io.netty.handler.ssl.util.InsecureTrustManagerFactory; import io.netty.handler.stream.ChunkedWriteHandler; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; +import java.io.File; public class ChildChannelHandler extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { -// String path = "D:\\Program Files\\Apache Software Foundation\\Tomcat 8.5-80\\cert\\6855055_zhentonggongsi.com.pfx"; -// String path = "/usr/local/server/apache-tomcat-80/conf/cert/6064978_okyueche.com.pfx"; +// String path = "C:\\app\\cert\\tomcat\\www.gzjwzc.com.pfx"; // SSLContext sslContext = createSSLContext.createSSLContext("PKCS12" -// , path, "jBOjj2fR"); -// SSLEngine 此类允许使用ssl安全套接层协议进行安全通信 +// , path, "79uc9bsd"); // SSLEngine engine = sslContext.createSSLEngine(); -// engine.setUseClientMode(false); -// socketChannel.pipeline().addLast("ssl", new SslHandler(engine)); + + + File path = new File("/root/server/app/cert/qytzt.cn.key"); + File path1 = new File("/root/server/app/cert/qytzt.cn.pem"); + SslContext sslContext = SslContextBuilder.forServer(path, path1, null).clientAuth(ClientAuth.NONE).build(); + + //SSLEngine 此类允许使用ssl安全套接层协议进行安全通信 + SSLEngine engine = sslContext.newEngine(socketChannel.alloc()); + engine.setUseClientMode(false); + socketChannel.pipeline().addLast("ssl", new SslHandler(engine)); // 设置30秒没有读到数据,则触发一个READER_IDLE事件。 // pipeline.addLast(new IdleStateHandler(30, 0, 0)); diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/ClientPingMessage.java b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/ClientPingMessage.java similarity index 95% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/ClientPingMessage.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/applets/ClientPingMessage.java index 93a8497..9f1b0c3 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/ClientPingMessage.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/ClientPingMessage.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util.applets; +package com.sinata.push.util.applets; import java.io.Serializable; diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/Global.java b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/Global.java similarity index 87% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/Global.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/applets/Global.java index 1f3fa95..09c090e 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/Global.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/Global.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util.applets; +package com.sinata.push.util.applets; import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/NettyServer0.java b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/NettyServer0.java similarity index 95% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/NettyServer0.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/applets/NettyServer0.java index 7f2fa38..2474da7 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/NettyServer0.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/NettyServer0.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util.applets; +package com.sinata.push.util.applets; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; @@ -64,7 +64,7 @@ // ChildChannelHandler 对出入的数据进行的业务操作,其继承ChannelInitializer b.childHandler(new ChildChannelHandler()); System.out.println("服务端开启等待客户端连接 ... ..."); - Channel ch = b.bind(5300).sync().channel(); + Channel ch = b.bind(8888).sync().channel(); ch.closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); diff --git a/MessagePushTravel/src/main/java/com/sinata/push/util/applets/NettyWebSocketController.java b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/NettyWebSocketController.java new file mode 100644 index 0000000..da05e85 --- /dev/null +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/NettyWebSocketController.java @@ -0,0 +1,198 @@ +package com.sinata.push.util.applets; + + +import com.alibaba.fastjson.JSONObject; +import com.sinata.push.util.SinataUtil; +import com.sinata.push.util.SpringUtil; +import com.sinata.push.util.StringUtil; +import com.sinata.push.util.echo.Method; +import com.sinata.push.util.echo.NettyChannelMap; +import com.sinata.push.util.echo.NettyMsg; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Timer; +import java.util.TimerTask; + +public class NettyWebSocketController { + + public static Hashtable<String, Hashtable<ChannelHandlerContext, String>> map = new Hashtable<String, Hashtable<ChannelHandlerContext,String>>(); + + private RedisTemplate<String, String> redisTemplate = SpringUtil.getObject(StringRedisTemplate.class); + + public static Hashtable<String,String> table; + static{ + if(table == null){ + table = new Hashtable<>(); + } + } + + public static boolean isdebug = false; + public static int i = 0; + + + /** + * 判断客户端要执行什么操作 + * + * @param ctx + * @param msg + * @author TaoNingBo + */ + public void JudgeOperation(ChannelHandlerContext ctx, String msg) { + try { + // 验证即时通讯命令是否正确有效 + if(SinataUtil.isEmpty(msg)) { + return; + } + String msgStr = msg.toString(); + if(msgStr.indexOf("{") == -1 || msgStr.indexOf("}") == -1 || msgStr.indexOf("code") == -1 || msgStr.indexOf("msg") == -1 || msgStr.indexOf("data") == -1 || msgStr.indexOf("method") == -1) { + return; + } + if(isdebug) { +// System.out.println("<<<--receive-->>>111" + msg); + } + + // 获取socket信息,保存相应的socket + JSONObject jsonMsg = JSONObject.parseObject(msg.toString()); + int code = jsonMsg.getIntValue("code"); + String message = jsonMsg.getString("msg"); + String method = jsonMsg.getString("method"); + if(code != 200 || !message.equals("SUCCESS")) { + return; + } + JSONObject jsonCon = JSONObject.parseObject(jsonMsg.get("data").toString()); + // ############################### 心跳 ############################ + // 心跳 + if(method.equals(Method.ping)){ + String token = jsonCon.getString("token"); + String userId1 = jsonCon.getString("userId"); + if(StringUtil.isNotEmpty(userId1)){ + //确保账号在单个设备上登录 + if(StringUtil.isNotEmpty(token)){ + String token_ = (String)redisTemplate.opsForValue().get("USER_" + userId1);//获取缓存中最新的数据 + if(StringUtil.isNotEmpty(token_) && !token.equals(token_)){//不在同一设备上登录,向其他设备发送数据 + ChannelHandlerContext context = NettyChannelMap.getData("Applets" + userId1); + JSONObject msg_ = new JSONObject(); + msg_.put("code", 200); + msg_.put("msg", "SUCCESS"); + msg_.put("method", "OFFLINE"); + msg_.put("data", new Object()); + this.sendMsgToClient(context, msg_.toJSONString()); + TimerTask timerTask = new TimerTask() { + @Override + public void run() { + NettyChannelMap.remove(context); + } + }; + Timer timer = new Timer(); + timer.schedule(timerTask, 3000); + timer.cancel(); + } + if(StringUtil.isEmpty(token_)){//确保登录的时候存储token失败的情况 + redisTemplate.opsForValue().set("USER_" + userId1, token); + } + } + + //存储业务使用的通道 + if(null != ctx && ctx.channel().isActive()) { + NettyChannelMap.update("Applets" + userId1, ctx); + String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); + ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); + } + } + + + } + } catch (Exception e) { + if(isdebug) { + NettyWebSocketController.sendMsgToClient(ctx, "__error__" + msg.toString()); + } + e.printStackTrace(); + } +} + + /** + * 向客户端发送消息 + * + * @param ctx + * @param msg + * @author TaoNingBo + */ + public static void sendMsgToClient(ChannelHandlerContext ctx, String msg) { +// System.out.println(ctx.channel().isActive()); + if (ctx != null && ctx.channel().isActive()) { + ByteBuf buffer = Unpooled.copiedBuffer((msg).getBytes()); + ChannelFuture sync; + try { + sync = ctx.channel().writeAndFlush(new TextWebSocketFrame(msg)).sync(); + if(!sync.isSuccess()){ + boolean b = true; + for (int i = 0; i < 10; i++) { + ctx.wait(3000); + sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync(); + if(sync.isSuccess()){ + b = false; + break; + } + System.err.println("小程序-》推送不成功,将继续推送"+msg); + } + if(b){ + NettyChannelMap.remove(ctx); + } + } + } catch (Exception e) { + System.err.println("小程序-》推送发生异常,记录:"+msg); + NettyChannelMap.remove(ctx); + } + if(isdebug) { + System.err.println("小程序-》 <<<--send-->>>" + msg) ; + } + }else{ + System.err.println("小程序-》推送失败,长连接不存在"); + NettyChannelMap.remove(ctx); + } + } + + // **链接断开 将推送消息记录 + public static void sendMsgToClient(String cacheType, Integer id,String msg) { + ChannelHandlerContext ctx = NettyChannelMap.getData(cacheType + id); + if (ctx != null) { + ChannelFuture sync; + try { + sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync(); + if(!sync.isSuccess()){ + for (int i = 0; i < 10; i++) { + sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync();; + if(!sync.isSuccess()){ + sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync();; + System.err.println("推送不成功,将继续推送"+msg); + if(i == 9){ + table.put(cacheType+id, msg); + ctx.close(); + System.err.println("推送发生异常,记录:"+msg); + } + }else{ + break; + } + } + } + } catch (Exception e) { + table.put(cacheType+id, msg); + System.err.println("推送发生异常,记录:"+msg); + } + if(isdebug) { + System.err.println("<<<--send-->>>" + msg); + } + }else{ + table.put(cacheType+id, msg); + System.err.println("链接断开,记录:id="+cacheType+id+",消息:"+msg); + } + } +} diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/WebSocketHandler.java b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/WebSocketHandler.java similarity index 95% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/WebSocketHandler.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/applets/WebSocketHandler.java index 32c673c..5d3b425 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/WebSocketHandler.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/WebSocketHandler.java @@ -1,9 +1,9 @@ -package com.sinata.zuul.util.applets; +package com.sinata.push.util.applets; import com.alibaba.fastjson.JSONObject; -import com.sinata.zuul.util.echo.Method; -import com.sinata.zuul.util.echo.NettyChannelMap; -import com.sinata.zuul.util.echo.NettyMsg; +import com.sinata.push.util.echo.Method; +import com.sinata.push.util.echo.NettyChannelMap; +import com.sinata.push.util.echo.NettyMsg; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; @@ -23,7 +23,7 @@ //用于websocket握手的处理类 private WebSocketServerHandshaker handshaker; - private static final String WEB_SOCKET_URL = "ws://localhost:9090/websocket"; + private static final String WEB_SOCKET_URL = "wss://localhost:8808/websocket"; diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/createSSLContext.java b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/createSSLContext.java similarity index 96% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/createSSLContext.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/applets/createSSLContext.java index 8487513..900b727 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/applets/createSSLContext.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/applets/createSSLContext.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util.applets; +package com.sinata.push.util.applets; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/DiscardServerHandler.java b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/DiscardServerHandler.java similarity index 97% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/DiscardServerHandler.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/echo/DiscardServerHandler.java index 6edaf44..f83843a 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/DiscardServerHandler.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/DiscardServerHandler.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util.echo; +package com.sinata.push.util.echo; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; @@ -104,7 +104,7 @@ // System.err.println(insocket.getAddress() + ": Disconnect connection......"); } NettyChannelMap.remove(ctx); -// System.err.println("清除通道" + ctx); + System.err.println("清除通道" + ctx); // super.channelInactive(ctx); } diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/Method.java b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/Method.java similarity index 77% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/Method.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/echo/Method.java index aa3f100..cea0d88 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/Method.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/Method.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util.echo; +package com.sinata.push.util.echo; /** * 即时通讯【通讯类型类】 @@ -14,9 +14,6 @@ /** 心跳【接收】 */ public final static String ping = "PING"; - - /** 心跳【响应】 */ - public final static String pong = "PONG"; /** 司机上传位置 */ public static final String location = "LOCATION"; diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyChannelMap.java b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyChannelMap.java similarity index 79% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyChannelMap.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyChannelMap.java index b27fd8f..acd89f0 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyChannelMap.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyChannelMap.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util.echo; +package com.sinata.push.util.echo; import io.netty.channel.ChannelHandlerContext; @@ -91,18 +91,6 @@ } - public static synchronized void remove_(ChannelHandlerContext value) { - Set<String> strings = ctxMap.keySet(); - for(String key : strings){ - ChannelHandlerContext channelHandlerContext = ctxMap.get(key); - String s = channelHandlerContext.channel().remoteAddress().toString(); - String s1 = value.channel().remoteAddress().toString(); - if(s.equals(s1)){ - channelHandlerContext.close();//关闭通道 - ctxMap.remove(key); - } - } - } /** @@ -125,9 +113,4 @@ map.put(key, value); } - - - public static synchronized void update_(String key, ChannelHandlerContext value) { - ctxMap.put(key, value); - } } diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyMsg.java b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyMsg.java similarity index 98% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyMsg.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyMsg.java index 2f49fc0..37eee4e 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyMsg.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyMsg.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util.echo; +package com.sinata.push.util.echo; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyServer.java b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyServer.java similarity index 95% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyServer.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyServer.java index f9b605a..40206a7 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyServer.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyServer.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util.echo; +package com.sinata.push.util.echo; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; @@ -50,7 +50,7 @@ /** * 获取即时通讯启动端口 */ - private Integer nettyPort = 5200; + private Integer nettyPort = 9999; @Override public void run() { EventLoopGroup bossGroup = new NioEventLoopGroup(); @@ -61,7 +61,7 @@ bootstrap.channel(NioServerSocketChannel.class); bootstrap.option(ChannelOption.SO_BACKLOG, 1024); // 通过TCP_NODELAY禁用NAGLE,使消息立即发出去,不用等待到一定的数据量才发出去 - bootstrap.option(ChannelOption.TCP_NODELAY, true); + bootstrap.childOption(ChannelOption.TCP_NODELAY, true); // 保持长连接状态 bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); bootstrap.childHandler(new ServerInit() { diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyServerController.java b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyServerController.java similarity index 66% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyServerController.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyServerController.java index 1765dae..4e003bd 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/NettyServerController.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/NettyServerController.java @@ -1,20 +1,28 @@ -package com.sinata.zuul.util.echo; +package com.sinata.push.util.echo; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; -import com.sinata.zuul.util.*; +import com.sinata.push.util.*; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandlerContext; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; +import java.text.SimpleDateFormat; import java.util.*; +import java.util.concurrent.TimeUnit; /** @@ -29,11 +37,9 @@ public static Hashtable<String,String> table; - private RedisUtil redisUtil = SpringUtil.getObject(RedisUtil.class); + private RedisTemplate<String, String> redisTemplate = SpringUtil.getObject(StringRedisTemplate.class); - private GDMapGeocodingUtil gdMapGeocodingUtil = SpringUtil.getObject(GDMapGeocodingUtil.class); - - private RestTemplate internalRestTemplate = SpringUtil.getObject(RestTemplate.class); + private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); @@ -85,11 +91,6 @@ } JSONObject jsonCon = JSONObject.parseObject(jsonMsg.get("data").toString()); - if(null != ctx && ctx.channel().isActive()){ - jsonMsg.put("method", Method.pong); - sendMsgToClient(ctx, jsonMsg.toJSONString()); - } - //心跳 if(method.equals(Method.ping)) { Integer type = jsonCon.getInteger("type"); @@ -98,62 +99,74 @@ String device = jsonCon.getString("device"); String version = jsonCon.getString("version"); if(StringUtil.isNotEmpty(userId1)){ + String fluid_control = redisTemplate.opsForValue().get("fluid_control_" + userId1 + "_" + type); + if(!StringUtils.hasLength(fluid_control)){ + redisTemplate.opsForValue().set("fluid_control_" + userId1 + "_" + type, System.currentTimeMillis() + ""); + }else{ + long l = System.currentTimeMillis() - Long.valueOf(fluid_control); + if(l >= 10000){ + redisTemplate.opsForValue().set("fluid_control_" + userId1 + "_" + type, System.currentTimeMillis() + ""); + }else{ + String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); + ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); + return; + } + } - //判断用户或者司机长连接 + //判断用户或者司机长连接 if(type==1){ //确保账号在单个设备上登录 if(StringUtil.isNotEmpty(token)){ - String token_ = redisUtil.getValue("USER_APP_"+ userId1);//获取缓存中最新的数据 + String token_ = (String)redisTemplate.opsForValue().get("USER_" + userId1);//获取缓存中最新的数据 if(StringUtil.isNotEmpty(token_) && !token.equals(token_)){//不在同一设备上登录,向其他设备发送数据 - JSONObject msg_ = new JSONObject(); + ChannelHandlerContext context = NettyChannelMap.getData("USER" + userId1); + JSONObject msg_ = new JSONObject(); msg_.put("code", 200); msg_.put("msg", "SUCCESS"); msg_.put("method", "OFFLINE"); msg_.put("data", new Object()); - this.sendMsgToClient(ctx, msg_.toJSONString());//给当前通道发送消息 + this.sendMsgToClient(context, msg_.toJSONString());//给当前通道发送消息 TimerTask timerTask = new TimerTask() { @Override public void run() { - NettyChannelMap.remove_(ctx); - NettyChannelMap.remove(ctx); + NettyChannelMap.remove(context); } }; Timer timer = new Timer(); timer.schedule(timerTask, 3000); timer.cancel(); - }else{ - NettyChannelMap.update_(token.substring(0, 23), ctx); - NettyChannelMap.update("USER" + userId1, ctx); - String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); - ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); - } + } if(StringUtil.isEmpty(token_)){//确保登录的时候存储token失败的情况 - redisUtil.setStrValue("USER_APP_" + userId1, token); + redisTemplate.opsForValue().set("USER_" + userId1, token); } } - + //存储通讯通道 + if(null != ctx && ctx.channel().isActive()){ + System.err.println("开始存储用户通道:" + sdf.format(new Date()) + "----" + userId1); + NettyChannelMap.update("USER" + userId1, ctx); + String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); + ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); + } }else{ - //添加司机在线 - HttpHeaders headers = new HttpHeaders(); - // 以表单的方式提交 - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - //将请求头部和参数合成一个请求 - MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); - params.add("driverId", userId1); - params.add("device", (null != device && device.equals("carDevice")) ? "2" : "1"); - params.add("version", version); - HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers); - String w = internalRestTemplate.postForObject("http://driver-server/base/driverOnline/addDriverOnline",requestEntity , String.class); - JSONObject jsonObject = JSON.parseObject(w, JSONObject.class); + Map<String, Object> params = new HashMap<>(); + params.put("driverId", userId1); + HttpRequest post = HttpUtil.createPost(URLUtil.zuul + "/driver-server/base/driverOnline/addDriverOnline"); + post.contentType(MediaType.APPLICATION_FORM_URLENCODED.getType()); + post.form(params); + HttpResponse execute = post.execute(); + if(200 != execute.getStatus()){ + System.err.println("调用driver-server添加司机在线数据出错了"); + } + JSONObject jsonObject = JSON.parseObject(execute.body(), JSONObject.class); if(jsonObject.getIntValue("code") != 200){ System.err.println("调用driver-server添加司机在线数据出错了"); } //TODO 存储最后一次上传的时间(用于保证车载端断电后1小时自动下班) if(StringUtil.isNotEmpty(device) && device.equals("carDevice")){ - redisUtil.setStrValue("DEVICE_" + userId1, String.valueOf(System.currentTimeMillis())); + redisTemplate.opsForValue().set("DEVICE_" + userId1, String.valueOf(System.currentTimeMillis())); - String token_ = redisUtil.getValue("DRIVER_" + userId1);//缓存中拿最新数据 + String token_ = (String)redisTemplate.opsForValue().get("DRIVER_" + userId1);//缓存中拿最新数据 if(StringUtil.isNotEmpty(token_) && !token_.equals(token)){ //如果是车载端登录,则将其它端都强迫下线 JSONObject msg_ = new JSONObject(); @@ -165,63 +178,50 @@ TimerTask timerTask = new TimerTask() { @Override public void run() { - NettyChannelMap.remove_(ctx); NettyChannelMap.remove(ctx); } }; Timer timer = new Timer(); timer.schedule(timerTask, 3000); timer.cancel(); - }else{ -// System.err.println("开始存储司机通道" + userId1); - NettyChannelMap.update("DRIVER" + userId1, ctx); - NettyChannelMap.update_(token.substring(0, 23), ctx); - String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); - ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); } if(StringUtil.isEmpty(token_)){//确保登录的时候存储token失败的情况 - redisUtil.setStrValue("DRIVER_" + userId1, token); + redisTemplate.opsForValue().set("DRIVER_" + userId1, token); } } //确保账号在单个设备上登录 - String value = redisUtil.getValue("DEVICE_" + userId1); + String value = (String)redisTemplate.opsForValue().get("DEVICE_" + userId1); if(StringUtil.isNotEmpty(token) && StringUtil.isEmpty(value)){//APP端登录的操作 - String token_ = redisUtil.getValue("DRIVER_" + userId1);//缓存中拿最新数据 + String token_ = (String)redisTemplate.opsForValue().get("DRIVER_" + userId1);//缓存中拿最新数据 if(StringUtil.isNotEmpty(token_) && !token.equals(token_)){//不在同一设备上登录,向当前设备发送数据 - JSONObject msg_ = new JSONObject(); + ChannelHandlerContext context = NettyChannelMap.getData("DRIVER" + userId1); + JSONObject msg_ = new JSONObject(); msg_.put("code", 200); msg_.put("msg", "SUCCESS"); msg_.put("method", "OFFLINE"); msg_.put("data", new Object()); - this.sendMsgToClient(ctx, msg_.toJSONString());//给当前通道发送消息 + this.sendMsgToClient(context, msg_.toJSONString());//给当前通道发送消息 TimerTask timerTask = new TimerTask() { @Override public void run() { - NettyChannelMap.remove_(ctx); - NettyChannelMap.remove(ctx); + NettyChannelMap.remove(context); } }; Timer timer = new Timer(); timer.schedule(timerTask, 3000); timer.cancel(); - }else{ -// System.err.println("开始存储司机通道" + userId1); - NettyChannelMap.update("DRIVER" + userId1, ctx); - NettyChannelMap.update_(token.substring(0, 23), ctx); - String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); - ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); - } + } if(StringUtil.isEmpty(token_)){//确保登录的时候存储token失败的情况 - redisUtil.setStrValue("DRIVER_" + userId1, token); + redisTemplate.opsForValue().set("DRIVER_" + userId1, token); } } //存储通讯通道 if(null != ctx && ctx.channel().isActive()){ -// System.err.println("开始存储司机通道" + userId1); + System.err.println("开始存储司机通道:" + sdf.format(new Date()) + "----" + userId1); NettyChannelMap.update("DRIVER" + userId1, ctx); String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>()); ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes())); @@ -232,35 +232,49 @@ //司机上传位置 if(method.equals(Method.location)){ Integer driverId = jsonCon.getInteger("driverId"); + String fluid_control = (String)redisTemplate.opsForValue().get("location_" + driverId); + if(!StringUtils.hasLength(fluid_control)){ + redisTemplate.opsForValue().set("location_" + driverId, System.currentTimeMillis() + ""); + }else{ + long l = System.currentTimeMillis() - Long.valueOf(fluid_control); + if(l < 5000){ + return; + } + redisTemplate.opsForValue().set("location_" + driverId, System.currentTimeMillis() + ""); + } + Integer orderId = jsonCon.getInteger("orderId"); Integer orderType = jsonCon.getInteger("orderType"); Double lon = jsonCon.getDouble("lon"); Double lat = jsonCon.getDouble("lat"); Double computeAzimuth = jsonCon.getDouble("computeAzimuth"); Double altitude = jsonCon.getDouble("altitude"); + System.out.println("司机上传位置:" + sdf.format(new Date()) + "----" + driverId); if(SinataUtil.isNotEmpty(driverId)){ if(null != lon && 0 != lon && null != lat && 0 != lat){ if(null != orderId && 0 != driverId && null != orderType && 0 != orderType){//开始存入数据库 - HttpHeaders headers = new HttpHeaders(); - // 以表单的方式提交 - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - //将请求头部和参数合成一个请求 - MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(); - params.add("orderType", String.valueOf(orderType)); - params.add("orderId", String.valueOf(orderId)); - params.add("driverId", String.valueOf(driverId)); - params.add("lon", String.valueOf(lon)); - params.add("lat", String.valueOf(lat)); - params.add("directionAngle", String.valueOf(computeAzimuth)); - params.add("altitude", String.valueOf(altitude)); - HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers); - String s = internalRestTemplate.postForObject("http://driver-server/base/savePosition",requestEntity , String.class); - JSONObject jsonObject = JSON.parseObject(s, JSONObject.class); + Map<String, Object> params = new HashMap<>(); + params.put("orderType", String.valueOf(orderType)); + params.put("orderId", String.valueOf(orderId)); + params.put("driverId", String.valueOf(driverId)); + params.put("lon", String.valueOf(lon)); + params.put("lat", String.valueOf(lat)); + params.put("directionAngle", String.valueOf(computeAzimuth)); + params.put("altitude", String.valueOf(altitude)); + HttpRequest post = HttpUtil.createPost(URLUtil.zuul + "/driver-server/base/savePosition"); + post.contentType(MediaType.APPLICATION_FORM_URLENCODED.getType()); + post.form(params); + HttpResponse execute = post.execute(); + if(200 != execute.getStatus()){ + System.err.println("调用driver-server存储位置数据出错了"); + } + JSONObject jsonObject = JSON.parseObject(execute.body(), JSONObject.class); if(jsonObject.getIntValue("code") != 200){ System.err.println("调用driver-server存储位置数据出错了"); } } - redisUtil.setStrValue("DRIVER" + driverId, lon + "," + lat, 300);//实时位置存入redis中 + System.out.println("id:" + driverId + "---lon" + lon + "---lat" + lat); + redisTemplate.opsForValue().set("DRIVER" + driverId, lon + "," + lat, 300, TimeUnit.SECONDS);//实时位置存入redis中 }else{ NettyServerController.sendMsgToClient(ctx, "__error__" + msg.toString()); } diff --git a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/ServerInit.java b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/ServerInit.java similarity index 95% rename from ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/ServerInit.java rename to MessagePushTravel/src/main/java/com/sinata/push/util/echo/ServerInit.java index 3a50298..d0864e6 100644 --- a/ZuulQYTTravel/src/main/java/com/sinata/zuul/util/echo/ServerInit.java +++ b/MessagePushTravel/src/main/java/com/sinata/push/util/echo/ServerInit.java @@ -1,4 +1,4 @@ -package com.sinata.zuul.util.echo; +package com.sinata.push.util.echo; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; diff --git a/MessagePushTravel/src/main/resources/application.yml b/MessagePushTravel/src/main/resources/application.yml new file mode 100644 index 0000000..17d9797 --- /dev/null +++ b/MessagePushTravel/src/main/resources/application.yml @@ -0,0 +1,39 @@ +server: + port: 6000 +spring: + profiles: + active: prod + application: + name: message #服务名称 + servlet: + multipart: + max-request-size: 100MB + max-file-size: 100MB + data: + redis: + host: 172.21.35.151 + database: 0 + password: SC_cache@20#25 + time-out: 1000 + # 集群节点 + cluster: + nodes: 172.21.35.151:6512,172.21.35.152:6512,172.21.35.153:6512,172.21.35.151:6513,172.21.35.152:6513,172.21.35.153:6513 + # 重定向最大次数 + max-redirects: 3 + lettuce: + cluster: + refresh: + # 集群拓扑自适应刷新 + adaptive: true + # 集群拓扑刷新周期 毫秒 + period: 3000 + pool: + # 最大链接数量 + max-active: 100 + # 最大阻塞时间 负数没有限制 + max-wait: -1 + # 最大空闲链接 + max-idle: 10 + # 最小空闲链接 + min-idle: 0 + diff --git a/MessagePushTravel/src/main/resources/logback.xml b/MessagePushTravel/src/main/resources/logback.xml new file mode 100644 index 0000000..4e737fc --- /dev/null +++ b/MessagePushTravel/src/main/resources/logback.xml @@ -0,0 +1,222 @@ +<?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"> + <contextName>logback</contextName> + + <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义后,可以使“${}”来使用变量。 --> + <property name="log.path" value="/root/server/app/logs"/> + + <!--0. 日志格式和颜色渲染 --> + <!-- 彩色日志依赖的渲染类 --> + <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}}"/> + + <!--1. 输出到控制台--> + <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> + + <!--2. 输出到文档--> + <!-- 2.1 level为 DEBUG 日志,时间滚动输出 --> + <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <!-- 正在记录的日志文档的路径及文档名 --> + <file>${log.path}/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}/%d{yyyy-MM-dd}/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> + + <!-- 2.2 level为 INFO 日志,时间滚动输出 --> + <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <!-- 正在记录的日志文档的路径及文档名 --> + <file>${log.path}/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}/%d{yyyy-MM-dd}/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> + + <!-- 2.3 level为 WARN 日志,时间滚动输出 --> + <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <!-- 正在记录的日志文档的路径及文档名 --> + <file>${log.path}/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}/%d{yyyy-MM-dd}/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> + + <!-- 2.4 level为 ERROR 日志,时间滚动输出 --> + <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <!-- 正在记录的日志文档的路径及文档名 --> + <file>${log.path}/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}/%d{yyyy-MM-dd}/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> + + <!-- 2.5 所有 除了DEBUG级别的其它高于DEBUG的 日志,记录到一个文件 --> + <appender name="ALL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <!-- 正在记录的日志文档的路径及文档名 --> + <file>${log.path}/all.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}/%d{yyyy-MM-dd}/all-%d{yyyy-MM-dd}.%i.log</fileNamePattern> + <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> + <maxFileSize>100MB</maxFileSize> + </timeBasedFileNamingAndTriggeringPolicy> + <!--日志文档保留天数--> + <maxHistory>15</maxHistory> + </rollingPolicy> + <!-- 此日志文档记录除了DEBUG级别的其它高于DEBUG的 --> + <filter class="ch.qos.logback.classic.filter.LevelFilter"> + <level>DEBUG</level> + <onMatch>DENY</onMatch> + <onMismatch>ACCEPT</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"/> + --> + + <!-- + root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性 + level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, + 不能设置为INHERITED或者同义词NULL。默认是DEBUG + 可以包含零个或多个元素,标识这个appender将会添加到这个logger。 + --> + + <!-- 4 最终的策略: + 基本策略(root级) + 根据profile在启动时, logger标签中定制化package日志级别(优先级高于上面的root级)--> + <springProfile name="dev"> + <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" /> + <appender-ref ref="ALL_FILE" /> + </root> + <logger name="com.stylefeng.guns.modular.system.dao" level="debug"/> + </springProfile> + + <springProfile name="test"> + <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" /> + <appender-ref ref="ALL_FILE" /> + </root> + </springProfile> + + <springProfile name="prod"> + <root level="info"> + <!-- 生产环境最好不配置console写文件 --> + <appender-ref ref="DEBUG_FILE" /> + <appender-ref ref="INFO_FILE" /> + <appender-ref ref="WARN_FILE" /> + <appender-ref ref="ERROR_FILE" /> + <appender-ref ref="ALL_FILE" /> + </root> + </springProfile> + +</configuration> \ No newline at end of file diff --git a/ZuulQYTTravel/src/main/resources/static/tXQaRbVjpJ.txt b/MessagePushTravel/src/main/resources/static/tXQaRbVjpJ.txt similarity index 100% rename from ZuulQYTTravel/src/main/resources/static/tXQaRbVjpJ.txt rename to MessagePushTravel/src/main/resources/static/tXQaRbVjpJ.txt -- Gitblit v1.7.1