├── .DS_Store ├── gnss-common ├── .DS_Store ├── src │ └── main │ │ └── java │ │ └── com │ │ └── gnss │ │ └── common │ │ ├── model │ │ ├── BaseEnum.java │ │ └── BaseMessage.java │ │ ├── constants │ │ ├── AlarmActionEnum.java │ │ ├── ProtocolEnum.java │ │ ├── RpcEnum.java │ │ ├── CommandRequestTypeEnum.java │ │ ├── RoleTypeEnum.java │ │ ├── CommandSendResultEnum.java │ │ └── CommonConstants.java │ │ ├── dto │ │ ├── CommandMqDTO.java │ │ ├── TerminalDTO.java │ │ └── SuperiorConfigDTO.java │ │ ├── api │ │ └── CommonReplyParam.java │ │ ├── exception │ │ └── ApplicationException.java │ │ ├── annotations │ │ └── MessageService.java │ │ ├── security │ │ └── AuthTokenDetails.java │ │ ├── proto │ │ ├── LocationProtoDTO.java │ │ ├── RpcProto.java │ │ ├── TerminalProto.java │ │ ├── AlarmProtoDTO.java │ │ ├── MediaFileProtoDTO.java │ │ ├── CommandProto.java │ │ └── LocationProto.java │ │ ├── service │ │ ├── BaseMessageService.java │ │ └── RedisService.java │ │ ├── session │ │ └── Session.java │ │ ├── utils │ │ ├── CommonUtil.java │ │ ├── Jt808Util.java │ │ ├── JwtUtils.java │ │ └── SessionUtil.java │ │ └── event │ │ └── MessageServiceProvider.java └── pom.xml ├── gnss-mqutil ├── .DS_Store ├── src │ └── main │ │ └── java │ │ └── com │ │ └── gnss │ │ └── mqutil │ │ ├── constants │ │ └── MqConstants.java │ │ ├── converter │ │ └── ProtobufMessageConverter.java │ │ ├── configuration │ │ └── BaseConfiguration.java │ │ ├── consumer │ │ └── AbstractDownCommandReceiver.java │ │ └── producer │ │ └── RabbitMessageSender.java └── pom.xml ├── README.md ├── pom.xml └── LICENSE /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gnss-pro/common-project/HEAD/.DS_Store -------------------------------------------------------------------------------- /gnss-common/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gnss-pro/common-project/HEAD/gnss-common/.DS_Store -------------------------------------------------------------------------------- /gnss-mqutil/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gnss-pro/common-project/HEAD/gnss-mqutil/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | GNSS system for operating vehicles -- General specifications for data exchange between platforms. 2 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/model/BaseEnum.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | *

Description: 基础枚举

7 | *

Company: www.gps-pro.cn

8 | * 9 | * @author huangguangbin 10 | * @version 1.0.1 11 | * @date 2017/9/15 12 | */ 13 | public interface BaseEnum extends Serializable { 14 | T getValue(); 15 | } 16 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/constants/AlarmActionEnum.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.constants; 2 | 3 | /** 4 | *

Description: 报警动作

5 | *

Company: www.gps-pro.cn

6 | * 7 | * @author huangguangbin 8 | * @version 1.0.1 9 | * @date 2017/6/19 10 | */ 11 | public enum AlarmActionEnum { 12 | /** 13 | * 报警开始 14 | */ 15 | START, 16 | 17 | /** 18 | * 报警结束 19 | */ 20 | STOP; 21 | } 22 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/dto/CommandMqDTO.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | *

Description: 指令队列传输

9 | *

Company: www.gps-pro.cn

10 | * 11 | * @author huangguangbin 12 | * @version 1.0.1 13 | * @date 2018/2/3 14 | */ 15 | @Data 16 | public class CommandMqDTO { 17 | private Map params; 18 | private TerminalDTO terminalDto; 19 | } 20 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/model/BaseMessage.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.model; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | *

Description: 基础消息模型

10 | *

Company: www.gps-pro.cn

11 | * 12 | * @author huangguangbin 13 | * @version 1.0.1 14 | * @date 2018/9/15 15 | */ 16 | @Getter 17 | @Setter 18 | public class BaseMessage implements Serializable { 19 | 20 | /** 21 | * 消息体 22 | */ 23 | private byte[] msgBodyArr; 24 | } 25 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/constants/ProtocolEnum.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.constants; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | *

Description: 通信协议

7 | *

Company: www.gps-pro.cn

8 | * 9 | * @author huangguangbin 10 | * @version 1.0.1 11 | * @date 2017/6/19 12 | */ 13 | public enum ProtocolEnum { 14 | /** 15 | * 部标JT808 16 | */ 17 | JT808("JT808"); 18 | 19 | @Getter 20 | private String desc; 21 | 22 | ProtocolEnum(String desc) { 23 | this.desc = desc; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/constants/RpcEnum.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.constants; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | *

Description: RPC消息类型

7 | *

Company: www.gps-pro.cn

8 | * 9 | * @author huangguangbin 10 | * @version 1.0.1 11 | * @date 2018/2/3 12 | */ 13 | @Getter 14 | public enum RpcEnum { 15 | 16 | /** 17 | * 上级平台配置 18 | */ 19 | SUPERIOR_CONFIG("上级平台配置"); 20 | 21 | private String name; 22 | 23 | RpcEnum(String name) { 24 | this.name = name; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/dto/TerminalDTO.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.ToString; 6 | 7 | /** 8 | *

Description: 终端信息DTO

9 | *

Company: www.gps-pro.cn

10 | * 11 | * @author huangguangbin 12 | * @version 1.0.1 13 | * @date 2017/11/3 14 | */ 15 | @Getter 16 | @Setter 17 | @ToString 18 | public class TerminalDTO { 19 | private Long terminalId; 20 | private String terminalSimCode; 21 | private String terminalNum; 22 | private String vehicleNo; 23 | } 24 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/constants/CommandRequestTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.constants; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | *

Description: 指令请求方式

7 | *

Company: www.gps-pro.cn

8 | * 9 | * @author huangguangbin 10 | * @version 1.0.1 11 | * @date 2018/2/3 12 | */ 13 | @Getter 14 | public enum CommandRequestTypeEnum { 15 | /** 16 | * 同步方式 17 | */ 18 | SYNC("同步方式"), 19 | 20 | /** 21 | * 异步方式 22 | */ 23 | ASYNC("异步方式"); 24 | 25 | private String name; 26 | 27 | CommandRequestTypeEnum(String name) { 28 | this.name = name; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/constants/RoleTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.constants; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | *

Description: 角色类型

7 | *

Company: www.gps-pro.cn

8 | * 9 | * @author huangguangbin 10 | * @version 1.0.1 11 | * @date 2017/6/19 12 | */ 13 | @Getter 14 | public enum RoleTypeEnum { 15 | 16 | /** 17 | * 超级管理员 18 | */ 19 | SUPER_ADMIN("超级管理员"), 20 | 21 | /** 22 | * 普通管理员 23 | */ 24 | ADMIN("普通管理员"), 25 | 26 | /** 27 | * 普通用户 28 | */ 29 | USER("普通用户"), 30 | 31 | /** 32 | * 游客 33 | */ 34 | GUEST("游客"); 35 | 36 | /** 37 | * 描述 38 | */ 39 | private String desc; 40 | 41 | RoleTypeEnum(String desc) { 42 | this.desc = desc; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/api/CommonReplyParam.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.api; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | *

Description: 通用应答

10 | *

Company: www.gps-pro.cn

11 | * 12 | * @author huangguangbin 13 | * @version 1.0.1 14 | * @date 2018/2/3 15 | */ 16 | @Data 17 | public class CommonReplyParam { 18 | 19 | /** 20 | * 应答消息ID 21 | */ 22 | private String replyMessageId; 23 | 24 | /** 25 | * 结果 26 | */ 27 | private String result; 28 | 29 | /** 30 | * 附加信息 31 | */ 32 | private Map extraInfo = new HashMap<>(); 33 | 34 | public Map setExtraInfo(String key, Object value) { 35 | extraInfo.put(key, value); 36 | return extraInfo; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/exception/ApplicationException.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.exception; 2 | 3 | /** 4 | *

Description: 应用异常

5 | *

Company: www.gps-pro.cn

6 | * 7 | * @author huangguangbin 8 | * @version 1.0.1 9 | * @date 2017/9/15 10 | */ 11 | public class ApplicationException extends RuntimeException { 12 | 13 | public ApplicationException() { 14 | } 15 | 16 | public ApplicationException(String message) { 17 | super(message); 18 | } 19 | 20 | public ApplicationException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public ApplicationException(String message, Throwable cause) { 25 | super(message, cause); 26 | } 27 | 28 | protected ApplicationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 29 | super(message, cause, enableSuppression, writableStackTrace); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/annotations/MessageService.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.annotations; 2 | 3 | import com.gnss.common.constants.CommonConstants; 4 | import org.springframework.stereotype.Component; 5 | 6 | import java.lang.annotation.Documented; 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.RetentionPolicy; 10 | import java.lang.annotation.Target; 11 | 12 | @Target(ElementType.TYPE) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Documented 15 | @Component 16 | public @interface MessageService { 17 | 18 | /** 19 | * 消息ID 20 | * 21 | * @return 返回消息ID 22 | */ 23 | int messageId() default CommonConstants.DEFAULT_MESSAGE_ID; 24 | 25 | /** 26 | * 字符串类型的消息ID 27 | * 28 | * @return 返回字符串类型的消息ID 29 | */ 30 | String strMessageId() default ""; 31 | 32 | /** 33 | * 消息类型描述 34 | * 35 | * @return 返回消息类型描述 36 | */ 37 | String desc() default "不支持消息"; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/constants/CommandSendResultEnum.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.constants; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | *

Description: 指令发送结果

7 | *

Company: www.gps-pro.cn

8 | * 9 | * @author huangguangbin 10 | * @version 1.0.1 11 | * @date 2018/2/3 12 | */ 13 | @Getter 14 | public enum CommandSendResultEnum { 15 | /** 16 | * 成功 17 | */ 18 | SUCCESS(0, "成功"), 19 | 20 | /** 21 | * 失败 22 | */ 23 | FAILED(1, "失败"), 24 | 25 | /** 26 | * 终端不在线 27 | */ 28 | TERMINAL_OFFLINE(2, "终端不在线"), 29 | 30 | /** 31 | * 指令超时 32 | */ 33 | TIMEOUT(3, "指令超时"), 34 | 35 | /** 36 | * 指令不支持 37 | */ 38 | NOT_SUPPORT(4, "指令不支持"), 39 | 40 | /** 41 | * 内部服务错误 42 | */ 43 | INTERNAL_SERVER_ERROR(5, "内部服务错误"); 44 | 45 | private Integer code; 46 | 47 | private String desc; 48 | 49 | CommandSendResultEnum(Integer code, String desc) { 50 | this.code = code; 51 | this.desc = desc; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/security/AuthTokenDetails.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.security; 2 | 3 | import com.gnss.common.constants.RoleTypeEnum; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import lombok.ToString; 7 | 8 | import java.util.Date; 9 | 10 | /** 11 | *

Description: JWT详情

12 | *

Company: www.gps-pro.cn

13 | * 14 | * @author huangguangbin 15 | * @version 1.0.1 16 | * @date 2017/6/19 17 | */ 18 | @Getter 19 | @Setter 20 | @ToString 21 | public class AuthTokenDetails { 22 | /** 23 | * APP ID 24 | */ 25 | private String appId; 26 | /** 27 | * 用户ID 28 | */ 29 | private Long userId; 30 | /** 31 | * 组织ID 32 | */ 33 | private Long organizationId; 34 | /** 35 | * 角色ID 36 | */ 37 | private Long roleId; 38 | /** 39 | * 角色类型 40 | */ 41 | private RoleTypeEnum roleType; 42 | /** 43 | * 过期时间 44 | */ 45 | private Date expirationDate; 46 | /** 47 | * 语言环境 48 | */ 49 | private String language; 50 | } 51 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/constants/CommonConstants.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.constants; 2 | 3 | import java.time.ZoneId; 4 | 5 | /** 6 | *

Description: 公共常量

7 | *

Company: www.gps-pro.cn

8 | * 9 | * @author huangguangbin 10 | * @version 1.0.1 11 | * @date 2018/2/3 12 | */ 13 | public class CommonConstants { 14 | 15 | private CommonConstants() { 16 | } 17 | 18 | /** 19 | * 中国时区 20 | */ 21 | public static final ZoneId ZONE_GMT8 = ZoneId.of("GMT+8"); 22 | 23 | public static final int YES = 1; 24 | 25 | public static final int NO = 0; 26 | 27 | /** 28 | * 默认消息ID 29 | */ 30 | public static final int DEFAULT_MESSAGE_ID = -999; 31 | 32 | /** 33 | * 不支持的整型指令ID 34 | */ 35 | public static final int UNSUPPORT_MESSAGE_ID = -1; 36 | 37 | /** 38 | * 不支持的字符串指令ID 39 | */ 40 | public static final String UNSUPPORTED_STR_MESSAGE_ID = "unsupported"; 41 | 42 | /** 43 | * 默认编码 44 | */ 45 | public static final String DEFAULT_CHARSET_NAME = "GBK"; 46 | } 47 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/proto/LocationProtoDTO.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.proto; 2 | 3 | import com.baidu.bjf.remoting.protobuf.FieldType; 4 | import com.baidu.bjf.remoting.protobuf.annotation.Protobuf; 5 | import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | import lombok.ToString; 9 | 10 | import java.io.Serializable; 11 | 12 | /** 13 | *

Description: 位置传输对象protobuf定义

14 | *

Company: www.gps-pro.cn

15 | * 16 | * @author huangguangbin 17 | * @version 1.0.1 18 | * @date 2018/4/15 19 | */ 20 | @Getter 21 | @Setter 22 | @ToString 23 | @ProtobufClass 24 | public class LocationProtoDTO implements Serializable { 25 | 26 | /** 27 | * 节点名称 28 | */ 29 | @Protobuf(fieldType = FieldType.STRING, order = 1, required = true) 30 | private String nodeName; 31 | 32 | /** 33 | * 位置信息 34 | */ 35 | @Protobuf(fieldType = FieldType.OBJECT, order = 2, required = true) 36 | private LocationProto locationProto; 37 | 38 | /** 39 | * 终端信息 40 | */ 41 | @Protobuf(fieldType = FieldType.OBJECT, order = 3) 42 | private TerminalProto terminalProto; 43 | } 44 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/proto/RpcProto.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.proto; 2 | 3 | import com.baidu.bjf.remoting.protobuf.FieldType; 4 | import com.baidu.bjf.remoting.protobuf.annotation.Protobuf; 5 | import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass; 6 | import com.gnss.common.constants.RpcEnum; 7 | import lombok.Data; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | *

Description: RPC protobuf定义

13 | *

Company: www.gps-pro.cn

14 | * 15 | * @author huangguangbin 16 | * @version 1.0.1 17 | * @date 2018/2/3 18 | */ 19 | @Data 20 | @ProtobufClass 21 | public class RpcProto implements Serializable { 22 | 23 | /** 24 | * RPC类型 25 | */ 26 | @Protobuf(fieldType = FieldType.ENUM, order = 1, required = true) 27 | private RpcEnum rpcType; 28 | 29 | /** 30 | * 内容 31 | */ 32 | @Protobuf(fieldType = FieldType.STRING, order = 2) 33 | private String content; 34 | 35 | public RpcProto() { 36 | } 37 | 38 | public RpcProto(RpcEnum rpcType) { 39 | this.rpcType = rpcType; 40 | } 41 | 42 | public RpcProto(RpcEnum rpcType, String content) { 43 | this.rpcType = rpcType; 44 | this.content = content; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/proto/TerminalProto.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.proto; 2 | 3 | import com.baidu.bjf.remoting.protobuf.FieldType; 4 | import com.baidu.bjf.remoting.protobuf.annotation.Protobuf; 5 | import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | import lombok.ToString; 9 | 10 | import java.io.Serializable; 11 | 12 | /** 13 | *

Description: 终端protobuf定义

14 | *

Company: www.gps-pro.cn

15 | * 16 | * @author huangguangbin 17 | * @version 1.0.1 18 | * @date 2017/9/15 19 | */ 20 | @Getter 21 | @Setter 22 | @ToString 23 | @ProtobufClass 24 | public class TerminalProto implements Serializable { 25 | 26 | /** 27 | * 节点名称 28 | */ 29 | @Protobuf(fieldType = FieldType.STRING, order = 1, required = true) 30 | private String nodeName; 31 | 32 | /** 33 | * 终端ID 34 | */ 35 | @Protobuf(fieldType = FieldType.INT64, order = 2, required = true) 36 | private long terminalId; 37 | 38 | /** 39 | * 终端手机号 40 | */ 41 | @Protobuf(fieldType = FieldType.STRING, order = 3) 42 | private String terminalSimCode; 43 | 44 | /** 45 | * 终端号码 46 | */ 47 | @Protobuf(fieldType = FieldType.STRING, order = 4) 48 | private String terminalNum; 49 | 50 | /** 51 | * 车牌号码 52 | */ 53 | @Protobuf(fieldType = FieldType.STRING, order = 5) 54 | private String vehicleNum; 55 | } 56 | -------------------------------------------------------------------------------- /gnss-mqutil/src/main/java/com/gnss/mqutil/constants/MqConstants.java: -------------------------------------------------------------------------------- 1 | package com.gnss.mqutil.constants; 2 | 3 | /** 4 | *

Description: MQ常量

5 | *

Company: www.gps-pro.cn

6 | * 7 | * @author huangguangbin 8 | * @version 1.0.1 9 | * @date 2018/9/14 10 | */ 11 | public class MqConstants { 12 | private MqConstants() { 13 | } 14 | 15 | public static final String STATUS_EXCHANGE = "status.exchange"; 16 | 17 | public static final String STATUS_ROUTING_KEY = "#.status"; 18 | 19 | public static final String LOCATION_EXCHANGE = "location.exchange"; 20 | 21 | public static final String LOCATION_ROUTING_KEY = "#.location"; 22 | 23 | public static final String ALARM_EXCHANGE = "alarm.exchange"; 24 | 25 | public static final String ALARM_ROUTING_KEY = "#.alarm"; 26 | 27 | public static final String MEDIA_FILE_EXCHANGE = "media.file.exchange"; 28 | 29 | public static final String MEDIA_FILE_ROUTING_KEY = "#.media.file"; 30 | 31 | public static final String UP_COMMAND_EXCHANGE = "up.command.exchange"; 32 | 33 | public static final String UP_COMMAND_ROUTING_KEY = "#.up.command"; 34 | 35 | public static final String DOWN_COMMAND_EXCHANGE = "down.command.exchange"; 36 | 37 | public static final String DOWN_COMMAND_ROUTING_KEY = "#.down.command"; 38 | 39 | public static final String RPC_EXCHANGE = "rpc.exchange"; 40 | 41 | public static final String RPC_ROUTING_KEY = "gnss.rpc"; 42 | } -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/proto/AlarmProtoDTO.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.proto; 2 | 3 | import com.baidu.bjf.remoting.protobuf.FieldType; 4 | import com.baidu.bjf.remoting.protobuf.annotation.Protobuf; 5 | import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass; 6 | import com.gnss.common.constants.AlarmActionEnum; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | import lombok.ToString; 10 | 11 | import java.io.Serializable; 12 | import java.util.List; 13 | 14 | /** 15 | *

Description: 报警传输对象protobuf定义

16 | *

Company: www.gps-pro.cn

17 | * 18 | * @author huangguangbin 19 | * @version 1.0.1 20 | * @date 2018/4/15 21 | */ 22 | @Getter 23 | @Setter 24 | @ToString 25 | @ProtobufClass 26 | public class AlarmProtoDTO implements Serializable { 27 | 28 | /** 29 | * 报警动作 30 | */ 31 | @Protobuf(fieldType = FieldType.ENUM, order = 1, required = true) 32 | private AlarmActionEnum alarmAction; 33 | 34 | /** 35 | * 节点名称 36 | */ 37 | @Protobuf(fieldType = FieldType.STRING, order = 2, required = true) 38 | private String nodeName; 39 | 40 | /** 41 | * 位置信息 42 | */ 43 | @Protobuf(fieldType = FieldType.OBJECT, order = 3, required = true) 44 | private LocationProto locationProto; 45 | 46 | /** 47 | * 终端信息 48 | */ 49 | @Protobuf(fieldType = FieldType.OBJECT, order = 4, required = true) 50 | private TerminalProto terminalProto; 51 | 52 | /** 53 | * 报警位 54 | */ 55 | @Protobuf(fieldType = FieldType.INT32, order = 5, required = true) 56 | private List alarmBits; 57 | } 58 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/dto/SuperiorConfigDTO.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.dto; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | *

Description: JT809上级平台配置DTO

7 | *

Company: www.gps-pro.cn

8 | * 9 | * @author huangguangbin 10 | * @version 1.0.1 11 | * @date 2018/2/3 12 | */ 13 | @Data 14 | public class SuperiorConfigDTO { 15 | 16 | /** 17 | * 上级平台名称 18 | */ 19 | private String name; 20 | 21 | /** 22 | * 是否启用 23 | */ 24 | private String isEnable; 25 | 26 | /** 27 | * 上级平台IP 28 | */ 29 | private String superiorIp; 30 | 31 | /** 32 | * 上级平台端口 33 | */ 34 | private Integer superiorPort; 35 | 36 | /** 37 | * 本地IP 38 | */ 39 | private String localIp; 40 | 41 | /** 42 | * 本地端口 43 | */ 44 | private Integer localPort; 45 | 46 | /** 47 | * 接入码 48 | */ 49 | private Integer centerId; 50 | 51 | /** 52 | * 用户名 53 | */ 54 | private Integer userId; 55 | 56 | /** 57 | * 密码 58 | */ 59 | private String password; 60 | 61 | /** 62 | * 是否加密 63 | */ 64 | private String isCrypto; 65 | 66 | /** 67 | * 加密密钥 68 | */ 69 | private Integer cryptoKey; 70 | 71 | /** 72 | * 加密元素M1 73 | */ 74 | private Integer m1; 75 | 76 | /** 77 | * 加密元素IA1 78 | */ 79 | private Integer ia1; 80 | 81 | /** 82 | * 加密元素IC1 83 | */ 84 | private Integer ic1; 85 | 86 | /** 87 | * 平台编码 88 | */ 89 | private String platformId; 90 | 91 | /** 92 | * 版本标识 93 | */ 94 | private byte[] versionArr; 95 | } 96 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/service/BaseMessageService.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.service; 2 | 3 | import com.gnss.common.exception.ApplicationException; 4 | import com.gnss.common.model.BaseMessage; 5 | import com.gnss.common.proto.TerminalProto; 6 | import com.gnss.common.utils.SessionUtil; 7 | import io.netty.buffer.ByteBuf; 8 | import io.netty.channel.ChannelHandlerContext; 9 | import lombok.Getter; 10 | import lombok.Setter; 11 | 12 | /** 13 | *

Description: 消息处理器

14 | *

Company: www.gps-pro.cn

15 | * 16 | * @author huangguangbin 17 | * @version 1.0.1 18 | * @date 2017/9/15 19 | */ 20 | @Getter 21 | @Setter 22 | public abstract class BaseMessageService { 23 | 24 | private int messageId; 25 | 26 | private String strMessageId; 27 | 28 | private String desc; 29 | 30 | /** 31 | * 获取终端信息 32 | * 33 | * @param ctx ChannelHandlerContext 34 | * @return 终端信息 35 | */ 36 | public TerminalProto getTerminalInfo(ChannelHandlerContext ctx) { 37 | return SessionUtil.getTerminalInfo(ctx.channel()); 38 | } 39 | 40 | /** 41 | * 检查消息体长度 42 | * 43 | * @param msg 消息 44 | * @param msgBodyLen 消息体长度 45 | * @throws ApplicationException 应用异常 46 | */ 47 | public void checkMessageBodyLen(T msg, int msgBodyLen) throws ApplicationException { 48 | byte[] msgBody = msg.getMsgBodyArr(); 49 | if (msgBody.length < msgBodyLen) { 50 | throw new ApplicationException("消息体长度不对,不能小于" + msgBodyLen); 51 | } 52 | } 53 | 54 | /** 55 | * 处理消息 56 | * 57 | * @param ctx ChannelHandlerContext 58 | * @param msg 消息 59 | * @param msgBodyBuf 消息体 60 | * @return 返回结果 61 | * @throws Exception 异常 62 | */ 63 | public abstract Object process(ChannelHandlerContext ctx, T msg, ByteBuf msgBodyBuf) throws Exception; 64 | } 65 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/proto/MediaFileProtoDTO.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.proto; 2 | 3 | import com.baidu.bjf.remoting.protobuf.FieldType; 4 | import com.baidu.bjf.remoting.protobuf.annotation.Protobuf; 5 | import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | import lombok.ToString; 9 | 10 | import java.io.Serializable; 11 | 12 | /** 13 | *

Description: 多媒体文件传输对象protobuf定义

14 | *

Company: www.gps-pro.cn

15 | * 16 | * @author huangguangbin 17 | * @version 1.0.1 18 | * @date 2018/4/13 19 | */ 20 | @Getter 21 | @Setter 22 | @ToString(exclude = {"mediaData"}) 23 | @ProtobufClass 24 | public class MediaFileProtoDTO implements Serializable { 25 | /** 26 | * 多媒体ID 27 | */ 28 | @Protobuf(fieldType = FieldType.INT64, order = 1) 29 | private Long mediaId; 30 | 31 | /** 32 | * 多媒体类型 33 | */ 34 | @Protobuf(fieldType = FieldType.INT32, order = 2) 35 | private Integer mediaType; 36 | 37 | /** 38 | * 多媒体格式编码 39 | */ 40 | @Protobuf(fieldType = FieldType.INT32, order = 3) 41 | private Integer mediaFormatCode; 42 | 43 | /** 44 | * 事件项编码 45 | */ 46 | @Protobuf(fieldType = FieldType.INT32, order = 4) 47 | private Integer eventItemCode; 48 | 49 | /** 50 | * 通道ID 51 | */ 52 | @Protobuf(fieldType = FieldType.INT32, order = 5) 53 | private Integer channelId; 54 | 55 | /** 56 | * 位置信息 57 | */ 58 | @Protobuf(fieldType = FieldType.OBJECT, order = 6) 59 | private LocationProto location; 60 | 61 | /** 62 | * 多媒体数据 63 | */ 64 | @Protobuf(fieldType = FieldType.BYTES, order = 7, required = true) 65 | private byte[] mediaData; 66 | 67 | /** 68 | * 终端信息 69 | */ 70 | @Protobuf(fieldType = FieldType.OBJECT, order = 8, required = true) 71 | private TerminalProto terminalInfo; 72 | } 73 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/session/Session.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.session; 2 | 3 | import com.gnss.common.proto.TerminalProto; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import org.apache.commons.lang3.tuple.MutablePair; 7 | 8 | /** 9 | *

Description: 通信会话

10 | *

Company: www.gps-pro.cn

11 | * 12 | * @author huangguangbin 13 | * @version 1.0.1 14 | * @date 2018/11/1 15 | */ 16 | public class Session { 17 | 18 | /** 19 | * 消息流水号最小值 20 | */ 21 | public static final int DEFAULT_MIN_MSG_FLOW_ID = 0x0001; 22 | 23 | /** 24 | * 消息流水号最大值 25 | */ 26 | public static final int DEFAULT_MAX_MSG_FLOW_ID = 0x7FFF; 27 | 28 | /** 29 | * 终端信息 30 | */ 31 | @Getter 32 | @Setter 33 | private TerminalProto terminalInfo; 34 | 35 | /** 36 | * 手机号数组 37 | */ 38 | @Getter 39 | @Setter 40 | private byte[] phoneNumArr; 41 | 42 | /** 43 | * 消息流水号范围 44 | */ 45 | private final MutablePair msgFlowIdRange; 46 | 47 | /** 48 | * 当前消息流水号 49 | */ 50 | private int currentMsgFlowId; 51 | 52 | public Session(TerminalProto terminalInfo) { 53 | this.msgFlowIdRange = MutablePair.of(DEFAULT_MIN_MSG_FLOW_ID, DEFAULT_MAX_MSG_FLOW_ID); 54 | this.terminalInfo = terminalInfo; 55 | } 56 | 57 | public Session(Integer minMsgFlowId, Integer maxMsgFlowId, TerminalProto terminalInfo) { 58 | this.msgFlowIdRange = MutablePair.of(minMsgFlowId, maxMsgFlowId); 59 | this.terminalInfo = terminalInfo; 60 | } 61 | 62 | /** 63 | * 获取消息流水号,并设置下个消息流水号 64 | * 65 | * @return 返回消息流水号 66 | */ 67 | public int getNextMsgFlowId() { 68 | int msgFlowId = currentMsgFlowId; 69 | int minMsgFlowId = msgFlowIdRange.getLeft(); 70 | int maxMsgFlowId = msgFlowIdRange.getRight(); 71 | currentMsgFlowId = currentMsgFlowId >= maxMsgFlowId ? minMsgFlowId : currentMsgFlowId + 1; 72 | return msgFlowId; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/proto/CommandProto.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.proto; 2 | 3 | import com.baidu.bjf.remoting.protobuf.FieldType; 4 | import com.baidu.bjf.remoting.protobuf.annotation.Protobuf; 5 | import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass; 6 | import com.gnss.common.constants.CommandRequestTypeEnum; 7 | import com.gnss.common.constants.CommandSendResultEnum; 8 | import lombok.Data; 9 | 10 | import java.io.Serializable; 11 | 12 | /** 13 | *

Description: 指令MQ传输信息, 用于应用程序间上行下行指令传输

14 | *

Company: www.gps-pro.cn

15 | * 16 | * @author huangguangbin 17 | * @version 1.0.1 18 | * @date 2018/2/3 19 | */ 20 | @Data 21 | @ProtobufClass 22 | public class CommandProto implements Serializable { 23 | 24 | /** 25 | * 指令操作日志ID 26 | */ 27 | @Protobuf(fieldType = FieldType.INT64, order = 1, required = true) 28 | private long commandOperationLogId; 29 | 30 | /** 31 | * 终端ID 32 | */ 33 | @Protobuf(fieldType = FieldType.INT64, order = 2, required = true) 34 | private long terminalId; 35 | 36 | /** 37 | * 指令请求方式 38 | */ 39 | @Protobuf(fieldType = FieldType.ENUM, order = 3, required = true) 40 | private CommandRequestTypeEnum requestType; 41 | 42 | /** 43 | * 下行指令ID 44 | */ 45 | @Protobuf(fieldType = FieldType.STRING, order = 4, required = true) 46 | private String downCommandId; 47 | 48 | /** 49 | * 参数 50 | */ 51 | @Protobuf(fieldType = FieldType.STRING, order = 5) 52 | private String params; 53 | 54 | /** 55 | * 指令发送结果 56 | */ 57 | @Protobuf(fieldType = FieldType.ENUM, order = 6) 58 | private CommandSendResultEnum sendResult; 59 | 60 | /** 61 | * 响应指令ID 62 | */ 63 | @Protobuf(fieldType = FieldType.STRING, order = 7) 64 | private String respCommandId; 65 | 66 | /** 67 | * 发送方节点 68 | */ 69 | @Protobuf(fieldType = FieldType.STRING, order = 8, required = true) 70 | private String fromNode; 71 | 72 | /** 73 | * 接收方节点 74 | */ 75 | @Protobuf(fieldType = FieldType.STRING, order = 9, required = true) 76 | private String toNode; 77 | 78 | /** 79 | * 开始时间 80 | */ 81 | @Protobuf(fieldType = FieldType.INT64, order = 10, required = true) 82 | private long startTime; 83 | 84 | /** 85 | * 超时时间 86 | */ 87 | @Protobuf(fieldType = FieldType.INT32, order = 11) 88 | private Integer timeout; 89 | 90 | /** 91 | * 下行指令描述 92 | */ 93 | @Protobuf(fieldType = FieldType.STRING, order = 12) 94 | private String downCommandDesc; 95 | 96 | /** 97 | * 透传消息体 98 | */ 99 | @Protobuf(fieldType = FieldType.BYTES, order = 13) 100 | private byte[] messageBody; 101 | } 102 | -------------------------------------------------------------------------------- /gnss-mqutil/src/main/java/com/gnss/mqutil/converter/ProtobufMessageConverter.java: -------------------------------------------------------------------------------- 1 | package com.gnss.mqutil.converter; 2 | 3 | import com.baidu.bjf.remoting.protobuf.Codec; 4 | import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.reflections.Reflections; 7 | import org.springframework.amqp.core.Message; 8 | import org.springframework.amqp.core.MessageProperties; 9 | import org.springframework.amqp.support.converter.MessageConversionException; 10 | import org.springframework.amqp.support.converter.MessageConverter; 11 | 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | /** 16 | *

Description: Protobuf转换器

17 | *

Company: www.gps-pro.cn

18 | * 19 | * @author huangguangbin 20 | * @version 1.0.1 21 | * @date 2018/4/13 22 | */ 23 | @Slf4j 24 | public class ProtobufMessageConverter implements MessageConverter { 25 | private static Map codecMap = new HashMap<>(); 26 | 27 | static { 28 | Reflections reflections = new Reflections("com.gnss.common.proto"); 29 | reflections.getTypesAnnotatedWith(ProtobufClass.class).stream() 30 | .forEach(clazz -> { 31 | try { 32 | Codec codec = (Codec) Class.forName(clazz.getName() + "$$JProtoBufClass").newInstance(); 33 | codecMap.put(clazz.getSimpleName(), codec); 34 | log.info("加载Protobuf转换器{}", clazz.getName()); 35 | } catch (Exception e) { 36 | log.error("加载Protobuf转换器{}失败", clazz.getName(), e); 37 | } 38 | }); 39 | } 40 | 41 | @Override 42 | public Message toMessage(Object obj, MessageProperties messageProperties) throws MessageConversionException { 43 | String messageType = obj.getClass().getSimpleName(); 44 | Codec codec = codecMap.get(messageType); 45 | if (codec == null) { 46 | throw new MessageConversionException("不支持转换的消息类型:" + messageType); 47 | } 48 | messageProperties.setHeader("messageType", messageType); 49 | byte[] body; 50 | try { 51 | body = codec.encode(obj); 52 | } catch (Exception e) { 53 | throw new MessageConversionException("编码失败:" + messageType, e); 54 | } 55 | return new Message(body, messageProperties); 56 | } 57 | 58 | @Override 59 | public Object fromMessage(Message message) throws MessageConversionException { 60 | String messageType = message.getMessageProperties().getHeaders().get("messageType").toString(); 61 | Codec codec = codecMap.get(messageType); 62 | if (codec == null) { 63 | throw new MessageConversionException("不支持转换的消息类型:" + messageType); 64 | } 65 | Object obj; 66 | try { 67 | obj = codec.decode(message.getBody()); 68 | } catch (Exception e) { 69 | throw new MessageConversionException("解码失败:" + messageType, e); 70 | } 71 | return obj; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/utils/CommonUtil.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.utils; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.apache.commons.lang3.StringUtils; 6 | 7 | import java.net.InetSocketAddress; 8 | import java.time.LocalDate; 9 | 10 | /** 11 | *

Description: 工具类

12 | *

Company: www.gps-pro.cn

13 | * 14 | * @author huangguangbin 15 | * @version 1.0.1 16 | * @date 2018/9/16 17 | */ 18 | @Slf4j 19 | public class CommonUtil { 20 | 21 | private CommonUtil() { 22 | } 23 | 24 | /** 25 | * 格式化消息ID(转成0xXXXX) 26 | * 27 | * @param msgId 消息ID 28 | * @return 格式化字符串 29 | */ 30 | public static String formatMessageId(int msgId) { 31 | return toHexFormat(msgId, 4); 32 | } 33 | 34 | /** 35 | * 格式化数字 36 | * 37 | * @param num 数字 38 | * @param size 长度 39 | * @return 格式化字符串 40 | */ 41 | public static String toHexFormat(int num, int size) { 42 | return "0x" + hexStr(num, size); 43 | } 44 | 45 | /** 46 | * 转4位的十六进制字符串 47 | * 48 | * @param num 数字 49 | * @return 格式化字符串 50 | */ 51 | public static String hexStr(int num) { 52 | return hexStr(num, 4); 53 | } 54 | 55 | /** 56 | * 转十六进制字符串 57 | * 58 | * @param num 数字 59 | * @param size 长度 60 | * @return 格式化字符串 61 | */ 62 | public static String hexStr(int num, int size) { 63 | return StringUtils.leftPad(Integer.toHexString(num).toUpperCase(), size, '0'); 64 | } 65 | 66 | /** 67 | * 获取客户端IP 68 | * 69 | * @param ctx ChannelHandlerContext 70 | * @return 返回IP 71 | */ 72 | public static String getClientIp(ChannelHandlerContext ctx) { 73 | InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress(); 74 | return insocket.getAddress().getHostAddress(); 75 | } 76 | 77 | /** 78 | * 获取客户端端口 79 | * 80 | * @param ctx ChannelHandlerContext 81 | * @return 返回端口 82 | */ 83 | public static int getClientPort(ChannelHandlerContext ctx) { 84 | InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress(); 85 | return insocket.getPort(); 86 | } 87 | 88 | /** 89 | * 获取客户端IP信息 90 | * 91 | * @param ctx ChannelHandlerContext 92 | * @return 返回IP 93 | */ 94 | public static String getClientAddress(ChannelHandlerContext ctx) { 95 | InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress(); 96 | return String.format("%s:%d", insocket.getAddress().getHostAddress(), insocket.getPort()); 97 | } 98 | 99 | /** 100 | * 打印版权信息 101 | */ 102 | public static void printCopyright() { 103 | log.info("===================================================================================="); 104 | log.info("此程序未经授权不得擅自复制、传播、修改,如有上述行为我司均保留追究法律责任的权利。"); 105 | log.info("@Copyright: " + LocalDate.now().getYear() + " www.gps-pro.cn All rights reserved."); 106 | log.info("===================================================================================="); 107 | } 108 | } -------------------------------------------------------------------------------- /gnss-mqutil/src/main/java/com/gnss/mqutil/configuration/BaseConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.gnss.mqutil.configuration; 2 | 3 | import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer; 4 | import com.gnss.common.service.RedisService; 5 | import com.gnss.common.utils.CommonUtil; 6 | import com.gnss.mqutil.converter.ProtobufMessageConverter; 7 | import com.gnss.mqutil.producer.RabbitMessageSender; 8 | import org.springframework.amqp.core.AcknowledgeMode; 9 | import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; 10 | import org.springframework.amqp.rabbit.connection.ConnectionFactory; 11 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 12 | import org.springframework.beans.factory.annotation.Value; 13 | import org.springframework.context.annotation.Bean; 14 | import org.springframework.data.redis.connection.RedisConnectionFactory; 15 | import org.springframework.data.redis.core.StringRedisTemplate; 16 | 17 | /** 18 | *

Description: 基础bean配置

19 | *

Company: www.gps-pro.cn

20 | * 21 | * @author huangguangbin 22 | * @version 1.0.1 23 | * @date 2018-12-30 24 | */ 25 | public class BaseConfiguration { 26 | 27 | @Value("${gnss.middleware-ip}") 28 | private String host; 29 | 30 | /** 31 | * Redis模板 32 | * 33 | * @param connectionFactory 连接工厂 34 | * @return 35 | */ 36 | @Bean 37 | public StringRedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { 38 | StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(connectionFactory); 39 | GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer(); 40 | stringRedisTemplate.setValueSerializer(genericFastJsonRedisSerializer); 41 | stringRedisTemplate.setHashValueSerializer(genericFastJsonRedisSerializer); 42 | return stringRedisTemplate; 43 | } 44 | 45 | /** 46 | * Redis服务 47 | * 48 | * @param redisTemplate Redis模板 49 | * @return 50 | */ 51 | @Bean 52 | public RedisService redisService(StringRedisTemplate redisTemplate) { 53 | return new RedisService(redisTemplate); 54 | } 55 | 56 | /** 57 | * 配置接收消息的MessageConverter 58 | * 59 | * @param connectionFactory 连接工厂 60 | * @return 61 | */ 62 | @Bean 63 | public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) { 64 | SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); 65 | factory.setConnectionFactory(connectionFactory); 66 | factory.setPrefetchCount(50); 67 | factory.setConcurrentConsumers(5); 68 | factory.setMessageConverter(new ProtobufMessageConverter()); 69 | factory.setAcknowledgeMode(AcknowledgeMode.AUTO); 70 | return factory; 71 | } 72 | 73 | /** 74 | * 消息发送 75 | * 76 | * @param rabbitTemplate Rabbit模板 77 | * @param redisService Redis服务 78 | * @return 79 | */ 80 | @Bean 81 | public RabbitMessageSender rabbitMessageSender(RabbitTemplate rabbitTemplate, RedisService redisService) { 82 | CommonUtil.printCopyright(); 83 | return new RabbitMessageSender(rabbitTemplate, redisService); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/utils/Jt808Util.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.utils; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | *

Description: JT808工具

8 | *

Company: www.gps-pro.cn

9 | * 10 | * @author huangguangbin 11 | * @version 1.0.7 12 | * @date 2018-12-13 13 | */ 14 | public class Jt808Util { 15 | 16 | private static Map> paramTypeMap = new HashMap<>(); 17 | 18 | static { 19 | for (int i = 0x0001; i <= 0x0007; i++) { 20 | paramTypeMap.put(i, Integer.class); 21 | } 22 | for (int i = 0x0010; i <= 0x0017; i++) { 23 | paramTypeMap.put(i, String.class); 24 | } 25 | paramTypeMap.put(0x0018, Integer.class); 26 | paramTypeMap.put(0x0019, Integer.class); 27 | paramTypeMap.put(0x001A, String.class); 28 | paramTypeMap.put(0x001B, Integer.class); 29 | paramTypeMap.put(0x001C, Integer.class); 30 | paramTypeMap.put(0x001D, String.class); 31 | paramTypeMap.put(0x0020, Integer.class); 32 | paramTypeMap.put(0x0021, Integer.class); 33 | paramTypeMap.put(0x0022, Integer.class); 34 | paramTypeMap.put(0x0027, Integer.class); 35 | paramTypeMap.put(0x0028, Integer.class); 36 | paramTypeMap.put(0x0029, Integer.class); 37 | for (int i = 0x002C; i <= 0x0030; i++) { 38 | paramTypeMap.put(i, Integer.class); 39 | } 40 | paramTypeMap.put(0x0031, Short.class); 41 | for (int i = 0x0040; i <= 0x0044; i++) { 42 | paramTypeMap.put(i, String.class); 43 | } 44 | paramTypeMap.put(0x0045, Integer.class); 45 | paramTypeMap.put(0x0046, Integer.class); 46 | paramTypeMap.put(0x0047, Integer.class); 47 | paramTypeMap.put(0x0048, String.class); 48 | paramTypeMap.put(0x0049, String.class); 49 | for (int i = 0x0050; i <= 0x005A; i++) { 50 | paramTypeMap.put(i, Integer.class); 51 | } 52 | for (int i = 0x005B; i <= 0x005E; i++) { 53 | paramTypeMap.put(i, Short.class); 54 | } 55 | paramTypeMap.put(0x0064, Integer.class); 56 | paramTypeMap.put(0x0065, Integer.class); 57 | for (int i = 0x0070; i <= 0x0074; i++) { 58 | paramTypeMap.put(i, Integer.class); 59 | } 60 | paramTypeMap.put(0x0080, Integer.class); 61 | paramTypeMap.put(0x0081, Short.class); 62 | paramTypeMap.put(0x0082, Short.class); 63 | paramTypeMap.put(0x0083, String.class); 64 | paramTypeMap.put(0x0084, Byte.class); 65 | paramTypeMap.put(0x0090, Byte.class); 66 | paramTypeMap.put(0x0091, Byte.class); 67 | paramTypeMap.put(0x0092, Byte.class); 68 | paramTypeMap.put(0x0093, Integer.class); 69 | paramTypeMap.put(0x0094, Byte.class); 70 | paramTypeMap.put(0x0095, Integer.class); 71 | paramTypeMap.put(0x0100, Integer.class); 72 | paramTypeMap.put(0x0101, Short.class); 73 | paramTypeMap.put(0x0102, Integer.class); 74 | paramTypeMap.put(0x0103, Short.class); 75 | } 76 | 77 | private Jt808Util() { 78 | } 79 | 80 | /** 81 | * 获取JT808终端参数的类型 82 | * @param paramId 参数ID 83 | * @return 参数类型 84 | */ 85 | public static Class getParamType(int paramId) { 86 | return paramTypeMap.get(paramId); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/utils/JwtUtils.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.utils; 2 | 3 | import com.gnss.common.constants.RoleTypeEnum; 4 | import com.gnss.common.security.AuthTokenDetails; 5 | import io.jsonwebtoken.Claims; 6 | import io.jsonwebtoken.Jwts; 7 | import io.jsonwebtoken.SignatureAlgorithm; 8 | 9 | import java.util.Date; 10 | 11 | /** 12 | *

Description: JWT工具

13 | *

Company: www.gps-pro.cn

14 | * 15 | * @author huangguangbin 16 | * @version 1.0.1 17 | * @date 2017/6/19 18 | */ 19 | public class JwtUtils { 20 | 21 | private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512; 22 | private static final String SECRET_KEY = "mySecret"; 23 | private static final String APP_ID_FIELD = "appId"; 24 | private static final String ORGANIZATION_ID_FIELD = "account"; 25 | private static final String ROLE_ID_FIELD = "roleId"; 26 | private static final String ROLE_TYPE_FIELD = "roleType"; 27 | private static final String LANGUAGE_FIELD = "language"; 28 | 29 | /** 30 | * 生成token 31 | * 32 | * @param authTokenDetails 33 | * @return 34 | */ 35 | public static String generateToken(AuthTokenDetails authTokenDetails) { 36 | Long roleId = authTokenDetails.getRoleId(); 37 | String token = 38 | Jwts.builder().setSubject(authTokenDetails.getUserId().toString()) 39 | .claim(APP_ID_FIELD, authTokenDetails.getAppId()) 40 | .claim(ORGANIZATION_ID_FIELD, authTokenDetails.getOrganizationId().toString()) 41 | .claim(ROLE_ID_FIELD, roleId == null ? null : roleId.toString()) 42 | .claim(ROLE_TYPE_FIELD, authTokenDetails.getRoleType()) 43 | .claim(LANGUAGE_FIELD, authTokenDetails.getLanguage()) 44 | .setExpiration(authTokenDetails.getExpirationDate()) 45 | .signWith(SIGNATURE_ALGORITHM, SECRET_KEY) 46 | .compact(); 47 | return token; 48 | } 49 | 50 | /** 51 | * 解析token 52 | * 53 | * @param token 54 | * @return 55 | * @throws Exception 56 | */ 57 | public static AuthTokenDetails parseToken(String token) throws Exception { 58 | Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody(); 59 | String userId = claims.getSubject(); 60 | String appId = (String) claims.get(APP_ID_FIELD); 61 | String organizationId = (String) claims.get(ORGANIZATION_ID_FIELD); 62 | String roleId = (String) claims.get(ROLE_ID_FIELD); 63 | String roleType = (String) claims.get(ROLE_TYPE_FIELD); 64 | String language = (String) claims.get(LANGUAGE_FIELD); 65 | Date expirationDate = claims.getExpiration(); 66 | 67 | AuthTokenDetails authTokenDetails = new AuthTokenDetails(); 68 | authTokenDetails.setUserId(Long.valueOf(userId)); 69 | authTokenDetails.setAppId(appId); 70 | authTokenDetails.setOrganizationId(Long.valueOf(organizationId)); 71 | authTokenDetails.setRoleId(roleId == null ? null : Long.valueOf(roleId)); 72 | authTokenDetails.setRoleType(RoleTypeEnum.valueOf(roleType)); 73 | authTokenDetails.setExpirationDate(expirationDate); 74 | authTokenDetails.setLanguage(language); 75 | return authTokenDetails; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/proto/LocationProto.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.proto; 2 | 3 | import com.baidu.bjf.remoting.protobuf.FieldType; 4 | import com.baidu.bjf.remoting.protobuf.annotation.Protobuf; 5 | import com.baidu.bjf.remoting.protobuf.annotation.ProtobufClass; 6 | import com.gnss.common.constants.CommonConstants; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | import lombok.ToString; 10 | 11 | import java.io.Serializable; 12 | import java.util.List; 13 | 14 | /** 15 | *

Description: 位置protobuf定义

16 | *

Company: www.gps-pro.cn

17 | * 18 | * @author huangguangbin 19 | * @version 1.0.1 20 | * @date 2018/4/13 21 | */ 22 | @Getter 23 | @Setter 24 | @ToString 25 | @ProtobufClass 26 | public class LocationProto implements Serializable { 27 | 28 | /** 29 | * 是否在线 30 | */ 31 | @Protobuf(fieldType = FieldType.INT32, order = 1, required = true) 32 | private Integer online = CommonConstants.YES; 33 | 34 | /** 35 | * 是否定位:0未定位,1定位 36 | */ 37 | @Protobuf(fieldType = FieldType.INT32, order = 2) 38 | private Integer gpsValid; 39 | 40 | /** 41 | * ACC状态:0关,1开 42 | */ 43 | @Protobuf(fieldType = FieldType.INT32, order = 3) 44 | private Integer acc; 45 | 46 | /** 47 | * 纬度 48 | */ 49 | @Protobuf(fieldType = FieldType.DOUBLE, order = 4) 50 | private Double lat; 51 | 52 | /** 53 | * 经度 54 | */ 55 | @Protobuf(fieldType = FieldType.DOUBLE, order = 5) 56 | private Double lon; 57 | 58 | /** 59 | * 高程 60 | */ 61 | @Protobuf(fieldType = FieldType.INT32, order = 6) 62 | private Integer altitude; 63 | 64 | /** 65 | * 速度 66 | */ 67 | @Protobuf(fieldType = FieldType.DOUBLE, order = 7) 68 | private Double speed; 69 | 70 | /** 71 | * 方向 72 | */ 73 | @Protobuf(fieldType = FieldType.INT32, order = 8) 74 | private Integer direction; 75 | 76 | /** 77 | * 时间 78 | */ 79 | @Protobuf(fieldType = FieldType.INT64, order = 9) 80 | private Long time; 81 | 82 | /** 83 | * 里程 84 | */ 85 | @Protobuf(fieldType = FieldType.DOUBLE, order = 10) 86 | private Double mileage; 87 | 88 | /** 89 | * 油量 90 | */ 91 | @Protobuf(fieldType = FieldType.DOUBLE, order = 11) 92 | private Double fuel; 93 | 94 | /** 95 | * 行驶记录仪速度 96 | */ 97 | @Protobuf(fieldType = FieldType.DOUBLE, order = 12) 98 | private Double recoderSpeed; 99 | 100 | /** 101 | * 报警标志 102 | */ 103 | @Protobuf(fieldType = FieldType.INT64, order = 13) 104 | private Long alarmFlag; 105 | 106 | /** 107 | * 状态 108 | */ 109 | @Protobuf(fieldType = FieldType.INT64, order = 14) 110 | private Long status; 111 | 112 | /** 113 | * 附加信息 114 | */ 115 | @Protobuf(fieldType = FieldType.STRING, order = 15) 116 | private String extraInfo; 117 | 118 | /** 119 | * 报警位 120 | */ 121 | @Protobuf(fieldType = FieldType.INT32, order = 16) 122 | private List alarmBits; 123 | 124 | /** 125 | * 状态位 126 | */ 127 | @Protobuf(fieldType = FieldType.INT32, order = 17) 128 | private List statusBits; 129 | 130 | /** 131 | * 报警位(JSON字符串) 132 | */ 133 | @Protobuf(fieldType = FieldType.STRING, order = 18) 134 | private String alarmBitsJson; 135 | 136 | /** 137 | * 状态位(JSON字符串) 138 | */ 139 | @Protobuf(fieldType = FieldType.STRING, order = 19) 140 | private String statusBitsJson; 141 | } -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/utils/SessionUtil.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.utils; 2 | 3 | import com.gnss.common.proto.TerminalProto; 4 | import com.gnss.common.session.Session; 5 | import io.netty.channel.Channel; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.util.AttributeKey; 8 | import lombok.extern.slf4j.Slf4j; 9 | 10 | import java.util.Map; 11 | import java.util.Objects; 12 | import java.util.concurrent.ConcurrentHashMap; 13 | 14 | /** 15 | *

Description: 会话工具

16 | *

Company: www.gps-pro.cn

17 | * 18 | * @author huangguangbin 19 | * @version 1.0.1 20 | * @date 2018/11/1 21 | */ 22 | @Slf4j 23 | public class SessionUtil { 24 | 25 | private static final AttributeKey SESSION_ATTR = AttributeKey.newInstance("session"); 26 | 27 | private static final Map SESSION_MAP = new ConcurrentHashMap<>(); 28 | 29 | /** 30 | * 终端注册,如果重复登录则将上一个连接断开 31 | * 32 | * @param session 会话 33 | * @param channel socket通道 34 | * @return 返回boolean 35 | */ 36 | public static boolean bindSession(Session session, Channel channel) { 37 | final boolean[] isAbsent = {true}; 38 | Long terminalId = session.getTerminalInfo().getTerminalId(); 39 | SESSION_MAP.compute(terminalId, (k, v) -> { 40 | if (v != null) { 41 | v.close(); 42 | isAbsent[0] = false; 43 | } 44 | return channel; 45 | }); 46 | channel.attr(SESSION_ATTR).set(session); 47 | log.info("注册在线终端ID:{},数量:{}", terminalId, SESSION_MAP.size()); 48 | return isAbsent[0]; 49 | } 50 | 51 | /** 52 | * 终端注销,Channel跟注册的Channel相等才会移除 53 | * 54 | * @param channel socket通道 55 | * @return 返回boolean 56 | */ 57 | public static boolean unbindSession(Channel channel) { 58 | Session session = channel.attr(SESSION_ATTR).get(); 59 | if (session == null) { 60 | return false; 61 | } 62 | Long terminalId = session.getTerminalInfo().getTerminalId(); 63 | SESSION_MAP.computeIfPresent(terminalId, (k, v) -> { 64 | if (Objects.equals(channel, v)) { 65 | return null; 66 | } 67 | return v; 68 | }); 69 | channel.attr(SESSION_ATTR).set(null); 70 | log.info("注销在线终端ID:{},数量:{}", terminalId, SESSION_MAP.size()); 71 | return true; 72 | } 73 | 74 | /** 75 | * 获取终端信息 76 | * 77 | * @param ctx ChannelHandlerContext 78 | * @return 终端信息 79 | */ 80 | public static TerminalProto getTerminalInfo(ChannelHandlerContext ctx) { 81 | return ctx.channel().attr(SESSION_ATTR).get().getTerminalInfo(); 82 | } 83 | 84 | /** 85 | * 获取终端信息 86 | * 87 | * @param channel socket通道 88 | * @return 终端信息 89 | */ 90 | public static TerminalProto getTerminalInfo(Channel channel) { 91 | return channel.attr(SESSION_ATTR).get().getTerminalInfo(); 92 | } 93 | 94 | /** 95 | * 获取手机号码数组 96 | * @param channel socket通道 97 | * @return 手机号码数组 98 | */ 99 | public static byte[] getPhoneNum(Channel channel) { 100 | return channel.attr(SESSION_ATTR).get().getPhoneNumArr(); 101 | } 102 | 103 | /** 104 | * 获取消息流水号 105 | * 106 | * @param channel socket通道 107 | * @return 消息流水号 108 | */ 109 | public static int getNextMsgFlowId(Channel channel) { 110 | Session session = channel.attr(SESSION_ATTR).get(); 111 | return session.getNextMsgFlowId(); 112 | } 113 | 114 | /** 115 | * 是否登录 116 | * 117 | * @param ctx ChannelHandlerContext 118 | * @return 返回boolean 119 | */ 120 | public static boolean isLogin(ChannelHandlerContext ctx) { 121 | return ctx.channel().hasAttr(SESSION_ATTR); 122 | } 123 | 124 | /** 125 | * 根据终端ID获取Channel 126 | * @param terminalId 终端ID 127 | * @return socket通道 128 | */ 129 | public static Channel getChannel(Long terminalId) { 130 | return SESSION_MAP.get(terminalId); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/event/MessageServiceProvider.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.event; 2 | 3 | import com.gnss.common.annotations.MessageService; 4 | import com.gnss.common.constants.CommonConstants; 5 | import com.gnss.common.exception.ApplicationException; 6 | import com.gnss.common.service.BaseMessageService; 7 | import com.gnss.common.utils.CommonUtil; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.CommandLineRunner; 11 | import org.springframework.context.ApplicationContext; 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | import java.util.Objects; 16 | 17 | /** 18 | *

Description: 消息处理器提供

19 | *

Company: www.gps-pro.cn

20 | * 21 | * @author huangguangbin 22 | * @version 1.0.1 23 | * @date 2018/9/15 24 | */ 25 | @Slf4j 26 | public class MessageServiceProvider implements CommandLineRunner { 27 | 28 | @Autowired 29 | private ApplicationContext applicationContext; 30 | 31 | private Map> serviceMap = new HashMap<>(); 32 | 33 | private Map> strServiceMap = new HashMap<>(); 34 | 35 | @Override 36 | public void run(String... args) throws Exception { 37 | Map beansWithAnnotationMap = applicationContext.getBeansWithAnnotation(MessageService.class); 38 | for (Map.Entry entry : beansWithAnnotationMap.entrySet()) { 39 | registerMessageService(entry.getValue()); 40 | } 41 | if (!serviceMap.containsKey(CommonConstants.UNSUPPORT_MESSAGE_ID) && !strServiceMap.containsKey(CommonConstants.UNSUPPORTED_STR_MESSAGE_ID)) { 42 | throw new ApplicationException("请创建UnsupportedMessageService"); 43 | } 44 | } 45 | 46 | /** 47 | * 注册消息处理器 48 | * 49 | * @param registerObj 50 | */ 51 | private void registerMessageService(Object registerObj) { 52 | Class clazz = registerObj.getClass(); 53 | if (BaseMessageService.class.isAssignableFrom(clazz)) { 54 | MessageService annotation = clazz.getAnnotation(MessageService.class); 55 | int messageId = annotation.messageId(); 56 | String strMessageId = annotation.strMessageId(); 57 | String desc = annotation.desc(); 58 | BaseMessageService messageService = (BaseMessageService) registerObj; 59 | messageService.setDesc(desc); 60 | if (messageId != CommonConstants.DEFAULT_MESSAGE_ID) { 61 | messageService.setMessageId(messageId); 62 | serviceMap.put(messageId, messageService); 63 | String formatMsgId = messageId == CommonConstants.UNSUPPORT_MESSAGE_ID ? String.valueOf(CommonConstants.UNSUPPORT_MESSAGE_ID) : CommonUtil.formatMessageId(messageId); 64 | log.info("注册消息处理器,消息类型:{},消息描述:{},处理器:{}", formatMsgId, desc, clazz.getName()); 65 | } else if (!Objects.equals("", strMessageId)) { 66 | messageService.setStrMessageId(strMessageId); 67 | strServiceMap.put(strMessageId, messageService); 68 | log.info("注册消息处理器,消息类型:{},消息描述:{},处理器:{}", strMessageId, desc, clazz.getName()); 69 | } 70 | } 71 | } 72 | 73 | /** 74 | * 获取消息处理器 75 | * 76 | * @param messageId 消息ID 77 | * @return 返回BaseMessageService 78 | */ 79 | public BaseMessageService getMessageService(int messageId) { 80 | BaseMessageService messageService = serviceMap.get(messageId); 81 | if (messageService == null) { 82 | return serviceMap.get(CommonConstants.UNSUPPORT_MESSAGE_ID); 83 | } 84 | return messageService; 85 | } 86 | 87 | /** 88 | * 获取消息处理器 89 | * 90 | * @param strMessageId 字符串类型消息ID 91 | * @return 返回BaseMessageService 92 | */ 93 | public BaseMessageService getMessageService(String strMessageId) { 94 | BaseMessageService messageService = strServiceMap.get(strMessageId); 95 | if (messageService == null) { 96 | return strServiceMap.get(CommonConstants.UNSUPPORTED_STR_MESSAGE_ID); 97 | } 98 | return messageService; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /gnss-mqutil/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.gitee.gps-pro 7 | gnss-mqutil 8 | 1.0.10 9 | jar 10 | 11 | gnss-mqutil 12 | http://gps-pro.cn 13 | 14 | 15 | com.gitee.gps-pro 16 | common-project 17 | 1.0.7 18 | 19 | 20 | 21 | 22 | oss 23 | https://oss.sonatype.org/content/repositories/snapshots 24 | 25 | 26 | oss 27 | https://oss.sonatype.org/service/local/staging/deploy/maven2 28 | 29 | 30 | 31 | 32 | 33 | release 34 | 35 | 36 | 37 | org.apache.maven.plugins 38 | maven-source-plugin 39 | 3.0.1 40 | 41 | 42 | attach-sources 43 | 44 | jar-no-fork 45 | 46 | 47 | 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-javadoc-plugin 52 | 3.0.1 53 | 54 | 55 | 56 | date 57 | a 58 | date 59 | 60 | 61 | 62 | 63 | 64 | attach-javadocs 65 | 66 | jar 67 | 68 | 69 | 70 | 71 | 72 | org.apache.maven.plugins 73 | maven-gpg-plugin 74 | 1.6 75 | 76 | 77 | sign-artifacts 78 | verify 79 | 80 | sign 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | The Apache Software License, Version 2.0 93 | http://www.apache.org/licenses/LICENSE-2.0.txt 94 | 95 | 96 | 97 | 98 | https://gitee.com/gps-pro/common-project 99 | https://gitee.com/gps-pro/common-project.git 100 | https://gitee.com/gps-pro 101 | 102 | 103 | 104 | 105 | huangguangbin 106 | 406656983@qq.com 107 | http://gps-pro.cn 108 | 109 | 110 | 111 | 112 | 113 | com.gitee.gps-pro 114 | gnss-common 115 | ${gnss.common.version} 116 | 117 | 118 | 119 | org.springframework.boot 120 | spring-boot-starter-amqp 121 | 122 | 123 | 124 | org.apache.commons 125 | commons-lang3 126 | ${commons.lang3.version} 127 | 128 | 129 | 130 | com.alibaba 131 | fastjson 132 | ${fastjson.version} 133 | 134 | 135 | 136 | org.reflections 137 | reflections 138 | ${reflections.version} 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | org.sonatype.plugins 147 | nexus-staging-maven-plugin 148 | 1.6.7 149 | true 150 | 151 | oss 152 | https://oss.sonatype.org/ 153 | true 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /gnss-mqutil/src/main/java/com/gnss/mqutil/consumer/AbstractDownCommandReceiver.java: -------------------------------------------------------------------------------- 1 | package com.gnss.mqutil.consumer; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.gnss.common.api.CommonReplyParam; 5 | import com.gnss.common.constants.CommandSendResultEnum; 6 | import com.gnss.common.proto.CommandProto; 7 | import com.gnss.common.proto.TerminalProto; 8 | import com.gnss.common.utils.SessionUtil; 9 | import com.gnss.mqutil.producer.RabbitMessageSender; 10 | import io.netty.channel.Channel; 11 | import io.netty.channel.ChannelHandlerContext; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.amqp.core.Message; 14 | import org.springframework.amqp.rabbit.annotation.RabbitHandler; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | 17 | import java.util.HashMap; 18 | import java.util.HashSet; 19 | import java.util.List; 20 | import java.util.Map; 21 | import java.util.Set; 22 | import java.util.concurrent.ConcurrentHashMap; 23 | import java.util.concurrent.CopyOnWriteArrayList; 24 | 25 | /** 26 | *

Description: RabbitMQ下行指令订阅

27 | *

Company: www.gps-pro.cn

28 | * 29 | * @author huangguangbin 30 | * @version 1.0.1 31 | * @date 2018/9/14 32 | */ 33 | @Slf4j 34 | public abstract class AbstractDownCommandReceiver { 35 | 36 | @Autowired 37 | private RabbitMessageSender messageSender; 38 | 39 | private Map> respCommandMap = new HashMap<>(); 40 | 41 | private Map> downCommandMap = new ConcurrentHashMap<>(); 42 | 43 | /** 44 | * 订阅处理下行指令 45 | * 46 | * @param commandProto 指令信息 47 | * @param rabbitChannel rabbit通道 48 | * @param message 消息 49 | * @throws Exception 异常 50 | */ 51 | @RabbitHandler 52 | public void receiveDownCommand(CommandProto commandProto, com.rabbitmq.client.Channel rabbitChannel, Message message) throws Exception { 53 | try { 54 | //终端不在线 55 | Long terminalId = commandProto.getTerminalId(); 56 | Channel channel = SessionUtil.getChannel(terminalId); 57 | if (channel == null) { 58 | log.info("处理下发指令,终端不在线{}", commandProto); 59 | commandProto.setSendResult(CommandSendResultEnum.TERMINAL_OFFLINE); 60 | messageSender.sendUpCommand(commandProto); 61 | return; 62 | } 63 | 64 | registerDownCommand(commandProto); 65 | printLog(channel, commandProto); 66 | handleDownCommand(channel, commandProto); 67 | } catch (Exception e) { 68 | log.error("处理下发指令异常{}", commandProto, e); 69 | rabbitChannel.basicAck(message.getMessageProperties().getDeliveryTag(), false); 70 | } 71 | } 72 | 73 | private void registerDownCommand(CommandProto commandProto) { 74 | String respCommandId = commandProto.getRespCommandId(); 75 | if (respCommandId == null) { 76 | return; 77 | } 78 | String downCommandId = commandProto.getDownCommandId(); 79 | respCommandMap.computeIfAbsent(respCommandId, k -> new HashSet<>()).add(downCommandId); 80 | Long terminalId = commandProto.getTerminalId(); 81 | String key = String.format("%d-%s-%s", terminalId, downCommandId, respCommandId); 82 | downCommandMap.computeIfAbsent(key, k -> new CopyOnWriteArrayList<>()).add(commandProto); 83 | } 84 | 85 | private List unregisterDownCommand(Long terminalId, String downCommandId, String respCommandId) { 86 | String key = String.format("%d-%s-%s", terminalId, downCommandId, respCommandId); 87 | return downCommandMap.remove(key); 88 | } 89 | 90 | private void printLog(Channel channel, CommandProto commandProto) { 91 | TerminalProto terminalInfo = SessionUtil.getTerminalInfo(channel); 92 | log.info("下发指令:{}({}),终端ID:{},终端手机号:{},参数:{}", commandProto.getDownCommandId(), commandProto.getDownCommandDesc(), terminalInfo.getTerminalId(), terminalInfo.getTerminalSimCode(), commandProto.getParams()); 93 | } 94 | 95 | protected abstract void handleDownCommand(Channel channel, CommandProto commandProto) throws Exception; 96 | 97 | /** 98 | * 发送上行指令 99 | * 100 | * @param respCommandId 应答指令 101 | * @param result 结果 102 | * @param ctx ChannelHandlerContext 103 | * @throws Exception 异常 104 | */ 105 | public void sendUpCommand(ChannelHandlerContext ctx, String respCommandId, Object result) throws Exception { 106 | sendUpCommand(ctx.channel(), respCommandId, result); 107 | } 108 | 109 | /** 110 | * 发送上行指令 111 | * 112 | * @param respCommandId 应答指令 113 | * @param result 结果 114 | * @param channel Socket通道 115 | * @throws Exception 异常 116 | */ 117 | public void sendUpCommand(Channel channel, String respCommandId, Object result) throws Exception { 118 | Set downCommandIdSet = respCommandMap.get(respCommandId); 119 | if (downCommandIdSet == null) { 120 | return; 121 | } 122 | String downCommandId = null; 123 | if (result instanceof CommonReplyParam) { 124 | //通用应答需要判断应答的下行指令 125 | CommonReplyParam replyParam = (CommonReplyParam) result; 126 | downCommandId = replyParam.getReplyMessageId(); 127 | if (!downCommandIdSet.contains(downCommandId)) { 128 | log.error("未注册的下行指令:{},应答结果:{}", downCommandId, result); 129 | return; 130 | } 131 | } else { 132 | downCommandId = downCommandIdSet.stream().findFirst().get(); 133 | } 134 | 135 | TerminalProto terminalInfo = SessionUtil.getTerminalInfo(channel); 136 | Long terminalId = terminalInfo.getTerminalId(); 137 | List commandList = unregisterDownCommand(terminalId, downCommandId, respCommandId); 138 | if (commandList != null) { 139 | String resultJson = JSON.toJSONString(result); 140 | for (CommandProto commandProto : commandList) { 141 | commandProto.setParams(resultJson); 142 | commandProto.setSendResult(CommandSendResultEnum.SUCCESS); 143 | messageSender.sendUpCommand(commandProto); 144 | } 145 | log.info("发送上行指令,终端ID:{},终端手机号:{},下行指令:{},响应指令:{},响应结果:{}", terminalId, terminalInfo.getTerminalSimCode(), downCommandId, respCommandId, result); 146 | } 147 | } 148 | 149 | } -------------------------------------------------------------------------------- /gnss-common/src/main/java/com/gnss/common/service/RedisService.java: -------------------------------------------------------------------------------- 1 | package com.gnss.common.service; 2 | 3 | import com.gnss.common.proto.LocationProto; 4 | import com.gnss.common.proto.LocationProtoDTO; 5 | import com.gnss.common.proto.TerminalProto; 6 | import org.springframework.data.redis.core.HashOperations; 7 | import org.springframework.data.redis.core.StringRedisTemplate; 8 | 9 | import java.util.Map; 10 | import java.util.Objects; 11 | 12 | /** 13 | *

Description: Redis服务

14 | *

Company: www.gps-pro.cn

15 | * 16 | * @author huangguangbin 17 | * @version 1.0.1 18 | * @date 2018/11/5 19 | */ 20 | public class RedisService { 21 | 22 | private StringRedisTemplate redisTemplate; 23 | 24 | private HashOperations terminalHashOperations; 25 | 26 | private HashOperations locationHashOperations; 27 | 28 | public RedisService(StringRedisTemplate redisTemplate) { 29 | this.redisTemplate = redisTemplate; 30 | this.terminalHashOperations = redisTemplate.opsForHash(); 31 | this.locationHashOperations = redisTemplate.opsForHash(); 32 | } 33 | 34 | /** 35 | * Redis在线终端缓存Key 36 | */ 37 | private static final String TERMINAL_ONLINE_REDIS_KEY = "terminal-online"; 38 | 39 | /** 40 | * Redis终端信息缓存Key 41 | */ 42 | private static final String TERMINAL_INFO_REDIS_KEY = "terminal-info"; 43 | 44 | /** 45 | * Redis手机号缓存Key 46 | */ 47 | private static final String SIMCARD_REDIS_KEY = "simcard"; 48 | 49 | /** 50 | * Redis终端号码缓存Key 51 | */ 52 | private static final String TERMINAL_NUM_REDIS_KEY = "terminal-num"; 53 | 54 | /** 55 | * Redis车牌号码缓存Key 56 | */ 57 | private static final String VEHICLE_NUM_REDIS_KEY = "vehicle-num"; 58 | 59 | /** 60 | * Redis终端位置缓存Key 61 | */ 62 | private static final String LOCATION_REDIS_KEY = "location"; 63 | 64 | /** 65 | * 缓存在线终端 66 | * 67 | * @param terminalInfo 终端信息 68 | */ 69 | public void putOnlineTerminal(TerminalProto terminalInfo) { 70 | terminalHashOperations.put(TERMINAL_ONLINE_REDIS_KEY, String.valueOf(terminalInfo.getTerminalId()), terminalInfo); 71 | } 72 | 73 | /** 74 | * 获取在线终端 75 | * 76 | * @param terminalId 终端ID 77 | * @return 终端信息 78 | */ 79 | public TerminalProto getOnlineTerminal(Long terminalId) { 80 | return terminalHashOperations.get(TERMINAL_ONLINE_REDIS_KEY, String.valueOf(terminalId)); 81 | } 82 | 83 | /** 84 | * 删除在线终端 85 | * 86 | * @param terminalInfo 终端信息 87 | */ 88 | public void deleteOnlineTerminal(TerminalProto terminalInfo) { 89 | terminalHashOperations.delete(TERMINAL_ONLINE_REDIS_KEY, String.valueOf(terminalInfo.getTerminalId())); 90 | } 91 | 92 | /** 93 | * 删除某个节点的所有在线终端 94 | * 95 | * @param nodeName 节点名称 96 | */ 97 | public void deleteAllOnlineTerminals(String nodeName) { 98 | Map map = terminalHashOperations.entries(TERMINAL_ONLINE_REDIS_KEY); 99 | map.forEach((k, v) -> { 100 | if (Objects.equals(nodeName, v.getNodeName())) { 101 | terminalHashOperations.delete(TERMINAL_ONLINE_REDIS_KEY, k); 102 | } 103 | }); 104 | } 105 | 106 | /** 107 | * 缓存终端信息 108 | * 109 | * @param terminalInfo 终端信息 110 | */ 111 | public void putTerminalInfo(TerminalProto terminalInfo) { 112 | terminalHashOperations.put(TERMINAL_INFO_REDIS_KEY, String.valueOf(terminalInfo.getTerminalId()), terminalInfo); 113 | terminalHashOperations.put(SIMCARD_REDIS_KEY, String.valueOf(terminalInfo.getTerminalSimCode()), terminalInfo); 114 | terminalHashOperations.put(TERMINAL_NUM_REDIS_KEY, String.valueOf(terminalInfo.getTerminalNum()), terminalInfo); 115 | terminalHashOperations.put(VEHICLE_NUM_REDIS_KEY, String.valueOf(terminalInfo.getVehicleNum()), terminalInfo); 116 | } 117 | 118 | /** 119 | * 删除所有终端信息 120 | */ 121 | public void deleteAllTerminalInfo() { 122 | terminalHashOperations.entries(TERMINAL_INFO_REDIS_KEY) 123 | .forEach((k, v) -> terminalHashOperations.delete(TERMINAL_INFO_REDIS_KEY, k)); 124 | terminalHashOperations.entries(SIMCARD_REDIS_KEY) 125 | .forEach((k, v) -> terminalHashOperations.delete(SIMCARD_REDIS_KEY, k)); 126 | terminalHashOperations.entries(TERMINAL_NUM_REDIS_KEY) 127 | .forEach((k, v) -> terminalHashOperations.delete(TERMINAL_NUM_REDIS_KEY, k)); 128 | terminalHashOperations.entries(VEHICLE_NUM_REDIS_KEY) 129 | .forEach((k, v) -> terminalHashOperations.delete(VEHICLE_NUM_REDIS_KEY, k)); 130 | } 131 | 132 | /** 133 | * 获取终端信息 134 | * 135 | * @param terminalId 终端ID 136 | * @return 终端信息 137 | */ 138 | public TerminalProto getTerminalInfo(Long terminalId) { 139 | return terminalHashOperations.get(TERMINAL_INFO_REDIS_KEY, String.valueOf(terminalId)); 140 | } 141 | 142 | /** 143 | * 获取终端信息 144 | * 145 | * @param simCode 终端手机号 146 | * @return 终端信息 147 | */ 148 | public TerminalProto getTerminalInfoBySimCode(String simCode) { 149 | return terminalHashOperations.get(SIMCARD_REDIS_KEY, simCode); 150 | } 151 | 152 | /** 153 | * 获取终端信息 154 | * 155 | * @param terminalNum 终端号码 156 | * @return 终端信息 157 | */ 158 | public TerminalProto getTerminalInfoByTerminalNum(String terminalNum) { 159 | return terminalHashOperations.get(TERMINAL_NUM_REDIS_KEY, terminalNum); 160 | } 161 | 162 | /** 163 | * 获取终端信息 164 | * 165 | * @param vehicleNum 车牌号码 166 | * @return 终端信息 167 | */ 168 | public TerminalProto getTerminalInfoByVehicleNum(String vehicleNum) { 169 | return terminalHashOperations.get(VEHICLE_NUM_REDIS_KEY, vehicleNum); 170 | } 171 | 172 | /** 173 | * 缓存终端位置 174 | * 175 | * @param locationProtoDTO 位置信息 176 | */ 177 | public void putLastLocation(LocationProtoDTO locationProtoDTO) { 178 | locationHashOperations.put(LOCATION_REDIS_KEY, String.valueOf(locationProtoDTO.getTerminalProto().getTerminalId()), locationProtoDTO.getLocationProto()); 179 | } 180 | 181 | 182 | /** 183 | * 获取终端最新位置 184 | * 185 | * @param terminalId 终端ID 186 | * @return 187 | */ 188 | public LocationProto getLastLocation(Long terminalId) { 189 | return locationHashOperations.get(LOCATION_REDIS_KEY, String.valueOf(terminalId)); 190 | } 191 | 192 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.gitee.gps-pro 8 | common-project 9 | 1.0.7 10 | pom 11 | 12 | 13 | gnss-common 14 | gnss-mqutil 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-starter-parent 20 | 2.1.1.RELEASE 21 | 22 | 23 | 24 | 25 | 26 | oss 27 | https://oss.sonatype.org/content/repositories/snapshots 28 | 29 | 30 | oss 31 | https://oss.sonatype.org/service/local/staging/deploy/maven2 32 | 33 | 34 | 35 | 36 | 37 | release 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-source-plugin 43 | 3.0.1 44 | 45 | 46 | attach-sources 47 | 48 | jar-no-fork 49 | 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-javadoc-plugin 56 | 3.0.1 57 | 58 | 59 | 60 | date 61 | a 62 | date 63 | 64 | 65 | 66 | 67 | 68 | attach-javadocs 69 | 70 | jar 71 | 72 | 73 | 74 | 75 | 76 | org.apache.maven.plugins 77 | maven-gpg-plugin 78 | 1.6 79 | 80 | 81 | sign-artifacts 82 | verify 83 | 84 | sign 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | The Apache Software License, Version 2.0 97 | http://www.apache.org/licenses/LICENSE-2.0.txt 98 | 99 | 100 | 101 | 102 | https://gitee.com/gps-pro/common-project 103 | https://gitee.com/gps-pro/common-project.git 104 | https://gitee.com/gps-pro 105 | 106 | 107 | 108 | 109 | huangguangbin 110 | 406656983@qq.com 111 | http://gps-pro.cn 112 | 113 | 114 | 115 | 116 | UTF-8 117 | UTF-8 118 | 1.8 119 | 4.1.32.Final 120 | 1.2.54 121 | 3.8.1 122 | 2.2.5 123 | 0.9.1 124 | 0.9.11 125 | 1.0.10 126 | 127 | 128 | 129 | 130 | org.projectlombok 131 | lombok 132 | provided 133 | 134 | 135 | 136 | org.springframework.boot 137 | spring-boot-starter 138 | 139 | 140 | 141 | 142 | 143 | 144 | org.apache.maven.plugins 145 | maven-surefire-plugin 146 | 2.20 147 | 148 | true 149 | 150 | 151 | 152 | 153 | 154 | org.sonatype.plugins 155 | nexus-staging-maven-plugin 156 | 1.6.7 157 | true 158 | 159 | oss 160 | https://oss.sonatype.org/ 161 | true 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /gnss-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.gitee.gps-pro 8 | gnss-common 9 | 1.0.10 10 | jar 11 | 12 | gnss-common 13 | http://gps-pro.cn 14 | 15 | 16 | com.gitee.gps-pro 17 | common-project 18 | 1.0.7 19 | 20 | 21 | 22 | 23 | oss 24 | https://oss.sonatype.org/content/repositories/snapshots 25 | 26 | 27 | oss 28 | https://oss.sonatype.org/service/local/staging/deploy/maven2 29 | 30 | 31 | 32 | 33 | 34 | release 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-source-plugin 40 | 3.0.1 41 | 42 | 43 | attach-sources 44 | 45 | jar-no-fork 46 | 47 | 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-javadoc-plugin 53 | 3.0.1 54 | 55 | 56 | 57 | date 58 | a 59 | date 60 | 61 | 62 | 63 | 64 | 65 | attach-javadocs 66 | 67 | jar 68 | 69 | 70 | 71 | 72 | 73 | org.apache.maven.plugins 74 | maven-gpg-plugin 75 | 1.6 76 | 77 | 78 | sign-artifacts 79 | verify 80 | 81 | sign 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | The Apache Software License, Version 2.0 94 | http://www.apache.org/licenses/LICENSE-2.0.txt 95 | 96 | 97 | 98 | 99 | https://gitee.com/gps-pro/common-project 100 | https://gitee.com/gps-pro/common-project.git 101 | https://gitee.com/gps-pro 102 | 103 | 104 | 105 | 106 | huangguangbin 107 | 406656983@qq.com 108 | http://gps-pro.cn 109 | 110 | 111 | 112 | 113 | 114 | io.netty 115 | netty-all 116 | ${netty.version} 117 | compile 118 | 119 | 120 | 121 | org.apache.commons 122 | commons-lang3 123 | ${commons.lang3.version} 124 | 125 | 126 | 127 | com.baidu 128 | jprotobuf 129 | ${jprotobuf.version} 130 | 131 | 132 | 133 | org.springframework.data 134 | spring-data-redis 135 | compile 136 | 137 | 138 | 139 | com.alibaba 140 | fastjson 141 | ${fastjson.version} 142 | 143 | 144 | 145 | io.jsonwebtoken 146 | jjwt 147 | ${jjwt.version} 148 | 149 | 150 | 151 | 152 | 153 | 154 | com.baidu 155 | jprotobuf-precompile-plugin 156 | 2.0.3 157 | 158 | com.gnss.common.proto 159 | 160 | 161 | 162 | compile 163 | 164 | precompile 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | org.sonatype.plugins 173 | nexus-staging-maven-plugin 174 | 1.6.7 175 | true 176 | 177 | oss 178 | https://oss.sonatype.org/ 179 | true 180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /gnss-mqutil/src/main/java/com/gnss/mqutil/producer/RabbitMessageSender.java: -------------------------------------------------------------------------------- 1 | package com.gnss.mqutil.producer; 2 | 3 | import com.gnss.common.constants.AlarmActionEnum; 4 | import com.gnss.common.constants.CommonConstants; 5 | import com.gnss.common.proto.AlarmProtoDTO; 6 | import com.gnss.common.proto.CommandProto; 7 | import com.gnss.common.proto.LocationProto; 8 | import com.gnss.common.proto.LocationProtoDTO; 9 | import com.gnss.common.proto.MediaFileProtoDTO; 10 | import com.gnss.common.proto.RpcProto; 11 | import com.gnss.common.proto.TerminalProto; 12 | import com.gnss.common.service.RedisService; 13 | import com.gnss.mqutil.constants.MqConstants; 14 | import com.gnss.mqutil.converter.ProtobufMessageConverter; 15 | import lombok.extern.slf4j.Slf4j; 16 | import org.springframework.amqp.rabbit.connection.CorrelationData; 17 | import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate; 18 | import org.springframework.amqp.rabbit.core.RabbitTemplate; 19 | 20 | import java.util.List; 21 | import java.util.Map; 22 | import java.util.UUID; 23 | import java.util.stream.Collectors; 24 | 25 | import static java.util.stream.Collectors.partitioningBy; 26 | 27 | /** 28 | *

Description: RabbitMQ消息发送

29 | *

Company: www.gps-pro.cn

30 | * 31 | * @author huangguangbin 32 | * @version 1.0.1 33 | * @date 2018/4/13 34 | */ 35 | @Slf4j 36 | public class RabbitMessageSender { 37 | 38 | private RabbitTemplate rabbitTemplate; 39 | 40 | private RedisService redisService; 41 | 42 | public RabbitMessageSender(RabbitTemplate rabbitTemplate, RedisService redisService) { 43 | rabbitTemplate.setMessageConverter(new ProtobufMessageConverter()); 44 | RabbitMessagingTemplate rabbitMessagingTemplate = new RabbitMessagingTemplate(); 45 | rabbitMessagingTemplate.setRabbitTemplate(rabbitTemplate); 46 | this.rabbitTemplate = rabbitTemplate; 47 | this.redisService = redisService; 48 | } 49 | 50 | /** 51 | * 发送状态和位置 52 | * 53 | * @param terminalProto 终端信息 54 | * @param locationProto 位置信息 55 | * @return 位置传输信息 56 | * @throws Exception 异常 57 | */ 58 | public LocationProtoDTO sendStatusAndLocation(TerminalProto terminalProto, LocationProto locationProto) throws Exception { 59 | LocationProtoDTO locationProtoDTO = sendLocation(terminalProto, locationProto); 60 | String statusRoutingKey = String.format("%d.status", terminalProto.getTerminalId()); 61 | rabbitTemplate.convertAndSend(MqConstants.STATUS_EXCHANGE, statusRoutingKey, locationProtoDTO); 62 | return locationProtoDTO; 63 | } 64 | 65 | /** 66 | * 发送位置信息 67 | * 68 | * @param terminalProto 终端信息 69 | * @param locationProto 位置信息 70 | * @return 位置传输信息 71 | * @throws Exception 异常 72 | */ 73 | public LocationProtoDTO sendLocation(TerminalProto terminalProto, LocationProto locationProto) throws Exception { 74 | String nodeName = terminalProto.getNodeName(); 75 | LocationProtoDTO locationProtoDTO = new LocationProtoDTO(); 76 | locationProtoDTO.setNodeName(nodeName); 77 | locationProtoDTO.setLocationProto(locationProto); 78 | locationProtoDTO.setTerminalProto(terminalProto); 79 | String routingKey = String.format("%d.location", terminalProto.getTerminalId()); 80 | rabbitTemplate.convertAndSend(MqConstants.LOCATION_EXCHANGE, routingKey, locationProtoDTO); 81 | //有效位置处理完报警后放入缓存 82 | if (handleAlarm(locationProtoDTO)) { 83 | redisService.putLastLocation(locationProtoDTO); 84 | } 85 | return locationProtoDTO; 86 | } 87 | 88 | /** 89 | * 处理报警 90 | * 91 | * @param locationProtoDTO 位置传输信息 92 | * @return 93 | */ 94 | private boolean handleAlarm(LocationProtoDTO locationProtoDTO) { 95 | Long terminalId = locationProtoDTO.getTerminalProto().getTerminalId(); 96 | LocationProto currLocation = locationProtoDTO.getLocationProto(); 97 | LocationProto prevLocation = redisService.getLastLocation(terminalId); 98 | //最新位置必须是已定位 99 | if (currLocation.getGpsValid() == CommonConstants.NO) { 100 | return false; 101 | } 102 | //缓存不存在上一个位置,直接新增报警 103 | if (prevLocation == null) { 104 | sendAlarm(AlarmActionEnum.START, locationProtoDTO.getTerminalProto(), currLocation, currLocation.getAlarmBits()); 105 | return true; 106 | } 107 | //最新位置的时间不能小于上一个位置的时间 108 | if (currLocation.getTime() < prevLocation.getTime()) { 109 | return false; 110 | } 111 | 112 | TerminalProto terminalProto = locationProtoDTO.getTerminalProto(); 113 | List currAlarmBits = currLocation.getAlarmBits(); 114 | List prevAlarmBits = prevLocation.getAlarmBits(); 115 | Map> groups = currAlarmBits.stream() 116 | .collect(partitioningBy(t -> prevAlarmBits.contains(t))); 117 | //当前位置与上一个位置的交集 118 | List intersectList = groups.get(Boolean.TRUE); 119 | //当前位置与上一个位置的差集 120 | List currSubstractList = groups.get(Boolean.FALSE); 121 | //上一个位置与当前位置的差集 122 | List prevSubstractList = prevAlarmBits.stream() 123 | .filter(t -> !intersectList.contains(t)) 124 | .collect(Collectors.toList()); 125 | sendAlarm(AlarmActionEnum.STOP, terminalProto, prevLocation, prevSubstractList); 126 | sendAlarm(AlarmActionEnum.START, terminalProto, currLocation, currSubstractList); 127 | return true; 128 | } 129 | 130 | /** 131 | * 发送报警 132 | * 133 | * @param alarmAction 134 | * @param terminalProto 135 | * @param prevLocation 136 | * @param alarmBits 137 | */ 138 | private void sendAlarm(AlarmActionEnum alarmAction, TerminalProto terminalProto, LocationProto prevLocation, List alarmBits) { 139 | if (alarmBits.isEmpty()) { 140 | return; 141 | } 142 | AlarmProtoDTO alarmProtoDTO = new AlarmProtoDTO(); 143 | alarmProtoDTO.setAlarmAction(alarmAction); 144 | alarmProtoDTO.setNodeName(terminalProto.getNodeName()); 145 | alarmProtoDTO.setLocationProto(prevLocation); 146 | alarmProtoDTO.setTerminalProto(terminalProto); 147 | alarmProtoDTO.setAlarmBits(alarmBits); 148 | String routingKey = String.format("%d.%s.alarm", terminalProto.getTerminalId(), alarmAction == AlarmActionEnum.START ? "start" : "stop"); 149 | rabbitTemplate.convertAndSend(MqConstants.ALARM_EXCHANGE, routingKey, alarmProtoDTO); 150 | log.info("发送报警({}),终端信息:{},报警位:{}", alarmAction, terminalProto, alarmBits); 151 | } 152 | 153 | /** 154 | * 发送多媒体文件 155 | * 156 | * @param mediaFileDTO 多媒体文件 157 | * @throws Exception 异常 158 | */ 159 | public void sendMediaFile(MediaFileProtoDTO mediaFileDTO) throws Exception { 160 | String routingKey = String.format("%d.media.file", mediaFileDTO.getTerminalInfo().getTerminalId()); 161 | rabbitTemplate.convertAndSend(MqConstants.MEDIA_FILE_EXCHANGE, routingKey, mediaFileDTO); 162 | } 163 | 164 | /** 165 | * 发送下行指令 166 | * 167 | * @param commandProto 指令信息 168 | * @throws Exception 异常 169 | */ 170 | public void sendDownCommand(CommandProto commandProto) throws Exception { 171 | String nodeName = commandProto.getToNode(); 172 | String routingKey = String.format("%d.%s.down.command", commandProto.getTerminalId(), nodeName); 173 | rabbitTemplate.convertAndSend(MqConstants.DOWN_COMMAND_EXCHANGE, routingKey, commandProto); 174 | } 175 | 176 | /** 177 | * 发送上行指令 178 | * 179 | * @param commandProto 指令信息 180 | * @throws Exception 异常 181 | */ 182 | public void sendUpCommand(CommandProto commandProto) throws Exception { 183 | String nodeName = commandProto.getFromNode(); 184 | String routingKey = String.format("%d.%s.up.command", commandProto.getTerminalId(), nodeName); 185 | rabbitTemplate.convertAndSend(MqConstants.UP_COMMAND_EXCHANGE, routingKey, commandProto); 186 | } 187 | 188 | /** 189 | * 发送RPC请求 190 | * 191 | * @param rpcProto RPC信息 192 | * @return RPC结果 193 | * @throws Exception 异常 194 | */ 195 | public RpcProto sendAndReceive(RpcProto rpcProto) throws Exception { 196 | CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString()); 197 | Object response = rabbitTemplate.convertSendAndReceive(MqConstants.RPC_EXCHANGE, MqConstants.RPC_ROUTING_KEY, rpcProto, correlationId); 198 | return (RpcProto) response; 199 | } 200 | 201 | /** 202 | * 通知上线 203 | * 204 | * @param terminalProto 终端信息 205 | */ 206 | public void noticeOnline(TerminalProto terminalProto) { 207 | sendTerminalStatus(terminalProto.getNodeName(), terminalProto, CommonConstants.YES); 208 | } 209 | 210 | /** 211 | * 通知所有终端离线 212 | * 213 | * @param nodeName 节点名称 214 | */ 215 | public void noticeAllOffline(String nodeName) { 216 | sendTerminalStatus(nodeName, null, CommonConstants.NO); 217 | } 218 | 219 | /** 220 | * 通知离线 221 | * 222 | * @param terminalProto 终端信息 223 | */ 224 | public void noticeOffline(TerminalProto terminalProto) { 225 | sendTerminalStatus(terminalProto.getNodeName(), terminalProto, CommonConstants.NO); 226 | } 227 | 228 | /** 229 | * 发送终端状态 230 | * 231 | * @param nodeName 节点名称 232 | * @param terminalProto 终端信息 233 | * @param onlineStatus 在线状态 234 | */ 235 | private void sendTerminalStatus(String nodeName, TerminalProto terminalProto, int onlineStatus) { 236 | LocationProto locationProto = new LocationProto(); 237 | locationProto.setGpsValid(CommonConstants.NO); 238 | locationProto.setOnline(onlineStatus); 239 | LocationProtoDTO locationProtoDTO = new LocationProtoDTO(); 240 | locationProtoDTO.setNodeName(nodeName); 241 | locationProtoDTO.setTerminalProto(terminalProto); 242 | locationProtoDTO.setLocationProto(locationProto); 243 | String routingKey = terminalProto == null ? "all.status" : String.format("%d.status", terminalProto.getTerminalId()); 244 | rabbitTemplate.convertAndSend(MqConstants.STATUS_EXCHANGE, routingKey, locationProtoDTO); 245 | } 246 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------