jiazx0107@163.com
2023-12-12 46203ee88249d9a4046f3d453deb41edc562cf6c
提交网关心跳和设备状态
已删除1个文件
已修改19个文件
已添加6个文件
1860 ■■■■ 文件已修改
pom.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/api/Constant.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/api/utils/MyMD5Util.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/GatewayRunner.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/GatewayTimerScheduled.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/GatewayUtils.java 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/api/GatewayRemoteService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/hx2023/ScConstant.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/hx2023/data/DeviceStatusData.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/hx2023/data/HeartBeatData.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/hx2023/service/HxGatewayRemoteServiceImpl.java 213 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/hx2023/service/HxGatewayRemoteServiceImpl2.java 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/hx2023/util/Base64Utils.java 275 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/hx2023/util/OpenApiRsaSigner.java 283 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/hx2023/util/OpenApiSignatureUtils.java 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/service/GatewayDeviceService.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/util/GatewayHttpUtil.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/util/GatewayRSAUtils.java 367 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/fzzy/analysis/AnalysisSystem.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/fzzy/server/SessionListener.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/sdkhk/common/LPRCallBask_V31.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/weightyh/MessageConsumer.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-devGateway.yml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-devGatewayCommon.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-proGateway.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -250,8 +250,12 @@
            <version>3.0.9</version>
        </dependency>
        <!-- hutool加密解密工具类 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.0.7</version>
        </dependency>
        <!-- é›†æˆhttpclient -->
        <dependency>
src/main/java/com/fzzy/api/Constant.java
@@ -324,38 +324,31 @@
        return contextDeviceMap.get(sn);
    }
    public static void updateCacheOnline(String sn, String ip, Integer port, boolean isCreate) {
        ApiCommonDevice device = getCommonDeviceCache(sn);
        if (null == device && isCreate) {
            device = new ApiCommonDevice();
    public static ApiCommonDevice getCommonDeviceCacheByIp(String ip) {
        if (null == ip) return null;
        if (contextDeviceMap.isEmpty()) return null;
        for (ApiCommonDevice device : contextDeviceMap.values()) {
            if (ip.equals(device)) return device;
        }
        if (null != device) {
            device.setIp(ip);
            device.setPort(port);
            device.setStatus(Constant.YN_Y);
            device.setCode("SUCCESS");
            device.setMsg("设备在线");
            device.setSn(ip);
            contextDeviceMap.put(device.getSn(), device);
        }
        return null;
    }
    public static void updateCacheOffline(String sn, String ip, Integer port, boolean isCreate) {
        ApiCommonDevice device = getCommonDeviceCache(sn);
    public static ApiCommonDevice updateCacheOffline(String ip, Integer port) {
        ApiCommonDevice device = getCommonDeviceCacheByIp(ip);
        if (null == device && isCreate) {
            device = new ApiCommonDevice();
        if (null == device) {
            return null;
        }
        if (null != device) {
            device.setIp(ip);
            device.setPort(port);
            device.setStatus(Constant.YN_N);
            device.setCode("ERROR");
            device.setMsg("设备离线");
            contextDeviceMap.put(device.getSn(), device);
        }
        return device;
    }
    public static void updateCache(ApiCommonDevice device) {
src/main/java/com/fzzy/api/utils/MyMD5Util.java
@@ -1,6 +1,8 @@
package com.fzzy.api.utils;
import org.springframework.util.DigestUtils;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
@@ -9,6 +11,10 @@
 *
 */
public class MyMD5Util {
    public static String charset = "UTF-8";
    /**
     * 1.java原生用法
@@ -19,7 +25,7 @@
    public static String encrypt(String dataStr) {
        try {
            MessageDigest m = MessageDigest.getInstance("MD5");
            m.update(dataStr.getBytes(StandardCharsets.UTF_8));
            m.update(dataStr.getBytes(charset));
            byte[] s = m.digest();
            StringBuilder result = new StringBuilder();
            for (byte b : s) {
@@ -38,17 +44,17 @@
     *
     * @return
     */
    public static String getMD5(String str) {
        String md5 = DigestUtils.md5DigestAsHex(str.getBytes());
    public static String getMD5(String str) throws Exception{
        String md5 = DigestUtils.md5DigestAsHex(str.getBytes(charset));
        return md5;
    }
    public static void main(String[] args) throws Exception {
        String data = AESUtils.decrypt("QG5j4Ihk04GTNSzbsvNmttCBQCLbC57si3lGric1bpVyRv2Fjiy+JG2W1G4r8pYwOUkGFdAu7Ou2Xcz/3C4w9rk8mJtva92ZOdYD1kJxDF9MxKC9LDTHo3XRIPfD5w5Hg38CHzamDcL1pMu8b8d4gOppa0EgWzC28rp+iedNnbY+4Zwu9ANRdW/1d0FYNjSFY3/2Oa8AqA4ufbsDp4U28mBpxQ9hxM6LzTFnbMSXe2xr12+LbyDtkvDaxDGyojZKEGKq+VItw4j8kKx5uD5TGPa+7jienfuiKbdkYFOkzZKY0nokqhqRMBCkJ4xx4aSbZjyP3l5VzB0z1WqKEocD0PNdI3PML9M8tt+AGjd9TWUgklhOl6v+yLorX815Wp9A08nsbDJK1klVlx84vc2dSHyR4u8ITYRlH74PmfeshxR3WGBB4OhD8/GVMUgPd4q8grW8vZoqqzqFrQcoVDc70P5t+Fsqz8BlxDtbwssVhpbF3/iuX2i+VrXKFtUQ1nIHLWJEZIf87BE/DtHrbm1epRJvsZlEWtQf63jydaM+gsnb18Mn5yUnEnESD4OtlgkbSvOdzxk3MKHsUoka9fn0h5y55hLy6EQGm4zlQopvxa0=","a34de38afad2fff932f569e4434fed35");
        System.out.println(getMD5(data));
        System.out.println(encrypt("{\"bgdh\":\"0754-88843381\",\"cfs\":17,\"czbz\":\"u\",\"czhm\":\"0754-88323996\",\"dwdm\":\"91440500190354212L\",\"dwlx\":\"19\",\"dwmc\":\"汕头市粮食企业集团公司\",\"dzyx\":\"lsjtccb@163.com\",\"fddbr\":\"林良忠\",\"frlxfs\":\"0754-88626738\",\"frsfzh\":\"511131196308124236\",\"jd\":116.73651,\"kqs\":3,\"qylxr\":\"林泳生\",\"wd\":23.37235,\"xzqhdm\":\"440500\",\"ygs\":0,\"yzbm\":\"515000\",\"zcdz\":\"汕头市珠池路33号\",\"zcrq\":\"1992-12-10\",\"zczb\":2328.0,\"zcze\":7524.71,\"zhgxsj\":\"2022-10-20 18:42:51\"}"));
        System.out.println(getMD5( "{\\\"bgdh\\\":\\\"0754-88843381\\\",\\\"cfs\\\":17,\\\"czbz\\\":\\\"u\\\",\\\"czhm\\\":\\\"0754-88323996\\\",\\\"dwdm\\\":\\\"91440500190354212L\\\",\\\"dwlx\\\":\\\"19\\\",\\\"dwmc\\\":\\\"汕头市粮食企业集团公司\\\",\\\"dzyx\\\":\\\"lsjtccb@163.com\\\",\\\"fddbr\\\":\\\"林良忠\\\",\\\"frlxfs\\\":\\\"0754-88626738\\\",\\\"frsfzh\\\":\\\"511131196308124236\\\",\\\"jd\\\":116.73651,\\\"kqs\\\":3,\\\"qylxr\\\":\\\"林泳生\\\",\\\"wd\\\":23.37235,\\\"xzqhdm\\\":\\\"440500\\\",\\\"ygs\\\":0,\\\"yzbm\\\":\\\"515000\\\",\\\"zcdz\\\":\\\"汕头市珠池路33号\\\",\\\"zcrq\\\":\\\"1992-12-10\\\",\\\"zczb\\\":2328.0,\\\"zcze\\\":7524.71,\\\"zhgxsj\\\":\\\"2022-10-20 18:42:51\\\"}"));
    }
}
src/main/java/com/fzzy/gateway/GatewayRunner.java
@@ -29,8 +29,12 @@
    @Override
    public void run(String... args) throws Exception {
        log.info("---------MQTT初始化--------------");
        mqttPublishService.init();
        //执行初始化方案
        //网关初始化
        log.info("---------网关设备初始化--------------");
        apiInitService.init();
@@ -38,9 +42,11 @@
        scheduled.doWeatherExe();
        //更新设备缓存
        log.info("---------设备缓存初始化--------------");
        apiInitService.updateDeviceCache();
        //初始化车牌识别
        log.info("---------车牌识别初始化--------------");
        apiInitService.initAllLpr();
    }
src/main/java/com/fzzy/gateway/GatewayTimerScheduled.java
@@ -55,7 +55,7 @@
     * <p>
     * å›ºå®šæ—¶é—´ï¼šæ¯é—´éš”10分钟执行一次
     */
    @Scheduled(cron = "0 0/10 * * * ?")
    @Scheduled(cron = "0 0/1 * * * ?")
    public void scheduled() {
        //网关的心跳执行
src/main/java/com/fzzy/gateway/GatewayUtils.java
@@ -21,11 +21,6 @@
    public static Map<String, GatewayDevice> cacheMapDeviceId = new HashMap<>();
    /**
     * è®¾å¤‡ç¼“å­˜
     */
    public static Map<String, GatewayDevice> cacheMapDeviceSn = new HashMap<>();
    /**
     * è®¾å¤‡ç¼“å­˜-只针对
     */
    public static Map<String, GatewayDevice> cacheMapDeviceWeight = new HashMap<>();
@@ -33,12 +28,14 @@
    public static void add2Cache(GatewayDevice device) {
        cacheMapDeviceId.put(device.getDeviceId(), device);
        cacheMapDeviceSn.put(device.getDeviceSn(), device);
        //保存地磅
        if (GatewayDeviceType.TYPE_01.getCode().equals(device.getType())) {
            cacheMapDeviceWeight.put(device.getDeviceId(), device);
        }
    }
    public static Collection<GatewayDevice> allCacheDevice() {
        return cacheMapDeviceId.values();
    }
    public static GatewayDevice getCacheByDeviceId(String deviceId) {
@@ -46,8 +43,33 @@
    }
    public static GatewayDevice getCacheByDeviceSn(String deviceSn) {
        return cacheMapDeviceSn.get(deviceSn);
        Collection<GatewayDevice> list = allCacheDevice();
        if (null == list || list.isEmpty()) return null;
        for (GatewayDevice device : list) {
            if (deviceSn.equals(device.getDeviceSn())) return device;
    }
        return null;
    }
    /**
     * é’ˆå¯¹ä¸€ä¸ªé€šè®¯åˆ†æœºå¯¹å¤šä¸ªä»“情况
     *
     * @param deviceSn
     * @return
     */
    public static List<GatewayDevice> getCacheByDeviceSn2(String deviceSn) {
        Collection<GatewayDevice> list = allCacheDevice();
        if (null == list || list.isEmpty()) return null;
        List<GatewayDevice> result = new ArrayList<>();
        for (GatewayDevice device : list) {
            if (deviceSn.equals(device.getDeviceSn())) result.add(device);
        }
        return result;
    }
    public static List<GatewayDevice> getCacheByDeviceType(String deviceType) {
        List<GatewayDevice> result = new ArrayList<>();
@@ -67,7 +89,7 @@
    public static void removeCache(GatewayDevice data) {
        cacheMapDeviceId.remove(data.getDeviceId());
        cacheMapDeviceSn.remove(data.getDeviceSn());
        //cacheMapDeviceSn.remove(data.getDeviceSn());
    }
    public static String getStatus(String sn) {
src/main/java/com/fzzy/gateway/api/GatewayRemoteService.java
@@ -31,4 +31,11 @@
     * @param gatewayConf
     */
    void pushInfo(GatewayConf gatewayConf);
    /**
     * èŽ·å–å½“å‰ç½‘å…³ä¸‹çš„è®¾å¤‡åˆ—è¡¨ï¼Œå¹¶ä¸ŠæŠ¥è®¾å¤‡çŠ¶æ€
     * @param gatewayConf
     */
    void pushDeviceStatus(GatewayConf gatewayConf);
}
src/main/java/com/fzzy/gateway/hx2023/ScConstant.java
@@ -18,6 +18,8 @@
    public static String MESSAGE_TYPE_INVOKE_FUNCTION = "INVOKE_FUNCTION";
    /**
     * ç²®æƒ…采指令
     */
@@ -32,10 +34,13 @@
        return UUID.randomUUID().toString().replaceAll("-", "");
    }
//    public static String getMd5MessageId() {
//        return MyMD5Util.getMD5(getUUID());
//    }
    //API_SOURCE-心跳
    public static String API_SOURCE_TARGET_EQUIPMENT_HEARTBEAT = "TARGET_EQUIPMENT_HEARTBEAT";
    //API_SOURCE-网关设备状态消息的
    public static String API_SOURCE_TARGET_EQUIPMENT_STATUS = "TARGET_EQUIPMENT_STATUS";
    /**
     * ä¸‹å‘指令回复报文topic
@@ -47,4 +52,14 @@
     */
    public static String TOPIC_MESSAGE_REPORT = "/device/${productId}/${deviceId}/message/property/report";
    /**
     * ç½‘关设备状态消息消息 topic:TOPIC_EQUIPMENT_HEARTBEAT_{库点编码}
     */
    public static String TOPIC_EQUIPMENT_HEARTBEAT = "TOPIC_EQUIPMENT_HEARTBEAT_{kqdm}";
    /**
     * ç½‘关设备状态消息消息 topic:TOPIC_EQUIPMENT_STATUS_{库点编码}
     */
    public static String TOPIC_EQUIPMENT_STATUS = "TOPIC_EQUIPMENT_STATUS_{kqdm}";
}
src/main/java/com/fzzy/gateway/hx2023/data/DeviceStatusData.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.fzzy.gateway.hx2023.data;
import lombok.Data;
@Data
public class DeviceStatusData {
    //UUID,消息编号
    private String messageId;
    //模块识别码
    private String apISource;
    //网关 ID
    private String gatewayId;
    //网关 IP
    private String gatewayIp;
    //产品 ID
    private String productId;
    //设备编号
    private String equipId;
    //0 ä»£è¡¨è®¾å¤‡ä¸åœ¨çº¿ 1,1 ä»£è¡¨è®¾å¤‡åœ¨çº¿
    private int status = 1;
    //上报时间 yyyy-MM-dd hh:mm:ss
    private String reportTime;
    //上报信息一些说明
    private String memo;
}
src/main/java/com/fzzy/gateway/hx2023/data/HeartBeatData.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.fzzy.gateway.hx2023.data;
import lombok.Data;
@Data
public class HeartBeatData {
    //UUID,消息编号
    private String messageId;
    //模块识别码
    private String apISource;
    //网关 ID
    private String gatewayId;
    //网关 IP
    private String gatewayIp;
    //网关 mac åœ°å€
    private String gatewayMac;
    //heartbeat é»˜è®¤ 1
    private int heartbeat = 1;
    //上报时间 yyyy-MM-dd hh:mm:ss
    private String reportTime;
    //上报信息一些说明
    private String memo;
}
src/main/java/com/fzzy/gateway/hx2023/service/HxGatewayRemoteServiceImpl.java
@@ -1,28 +1,35 @@
package com.fzzy.gateway.hx2023.service;
import com.alibaba.fastjson2.JSONObject;
import com.fzzy.api.Constant;
import com.fzzy.api.data.GatewayDeviceType;
import com.fzzy.api.data.PushProtocol;
import com.fzzy.api.utils.*;
import com.fzzy.api.utils.ContextUtil;
import com.fzzy.api.view.repository.ApiLogRep;
import com.fzzy.gateway.data.BaseResp;
import com.fzzy.gateway.service.GatewayConfService;
import com.fzzy.gateway.util.GatewayHttpUtil;
import com.fzzy.gateway.GatewayUtils;
import com.fzzy.gateway.api.GatewayRemoteService;
import com.fzzy.gateway.data.BaseResp;
import com.fzzy.gateway.entity.GatewayConf;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.gateway.hx2023.ScConstant;
import com.fzzy.gateway.hx2023.data.CloudResp;
import com.fzzy.gateway.util.GatewayRSAUtils;
import com.fzzy.gateway.hx2023.data.DeviceStatusData;
import com.fzzy.gateway.hx2023.data.HeartBeatData;
import com.fzzy.gateway.hx2023.kafka.KafkaDeviceReportService;
import com.fzzy.gateway.hx2023.util.OpenApiSignatureUtils;
import com.fzzy.gateway.service.GatewayConfService;
import com.fzzy.gateway.util.GatewayHttpUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.util.Comparator;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
@Slf4j
@@ -31,11 +38,15 @@
public class HxGatewayRemoteServiceImpl implements GatewayRemoteService {
    String charset = "utf-8";
    @Resource
    private ApiLogRep apiLogRep;
    @Resource
    private GatewayConfService gatewayConfService;
    @Resource
    private KafkaDeviceReportService kafkaDeviceReportService;
    @Override
@@ -73,9 +84,10 @@
            //获取 AccessToken æŽ¥å£
            String sign = getSign(params, gatewayConf.getPrivateKey());
            String sign = getSign(params, gatewayConf);
            params.put("sign", sign);
            url = gatewayConf.getApiUrl() + "reserver/api/token/apply";
            jsonStr = GatewayHttpUtil.doGet(url, params);
            log.info("---获取AccessToken接口-返回---{}", jsonStr);
            CloudResp respToken = JSONObject.parseObject(jsonStr, CloudResp.class);
@@ -98,34 +110,42 @@
    @Override
    public void heartbeat(GatewayConf gatewayConf) {
        log.info("------------定时心跳执行---------{}", gatewayConf.getKqmc());
        try {
            if (StringUtils.isEmpty(gatewayConf.getApiUrl())) {
                return;
            }
            gatewayConf = getCacheConf(gatewayConf.getKqdm());
            //网关心跳接口
            Map<String, String> params = new HashMap<>();
            params.put("token", gatewayConf.getAccessToken());
            params.put("gatewayId", gatewayConf.getGatewayId());
            params.put("gatewayIp", gatewayConf.getGatewayIp());
            params.put("gatewayMac", gatewayConf.getGatewayMac());
            params.put("heartbeat", "1");
            params.put("timestamp", System.currentTimeMillis() + "");
            String sign = getSign(params, gatewayConf.getPrivateKey());
            params.put("sign", sign);
            String url = gatewayConf.getApiUrl() + "reserver/api/iot/equipment/heartbeat";
            HeartBeatData heartBeatData = new HeartBeatData();
            String jsonStr = GatewayHttpUtil.doGet(url, params);
           // log.info("---网关心跳接口-返回---{}", jsonStr);
            heartBeatData.setMessageId(ContextUtil.getUUID());
            heartBeatData.setApISource(ScConstant.API_SOURCE_TARGET_EQUIPMENT_HEARTBEAT);
            heartBeatData.setGatewayId(gatewayConf.getGatewayId());
            heartBeatData.setGatewayIp(gatewayConf.getGatewayIp());
            heartBeatData.setGatewayMac(null == gatewayConf.getGatewayMac() ? "无" : gatewayConf.getGatewayMac());
            heartBeatData.setHeartbeat(1);
            heartBeatData.setReportTime(DateFormatUtils.format(new Date(), "yyyy-MM-dd hh:mm:ss"));
            heartBeatData.setMemo("FZZY");
            String topic = ScConstant.TOPIC_EQUIPMENT_HEARTBEAT;
            topic = topic.replace("{kqdm}", gatewayConf.getKqdm());
            String messageInfo = JSONObject.toJSONString(heartBeatData);
            log.info("---网关心跳推送--{}-{}", topic, messageInfo);
            kafkaDeviceReportService.publishWithTopic(messageInfo, topic);
        } catch (Exception e) {
            log.error("------网关心跳接口--执行失败-----{}", e);
        }
        //执行当前网关的设备状态推送
        pushDeviceStatus(gatewayConf);
    }
    @Override
@@ -142,13 +162,13 @@
            params.put("token", gatewayConf.getAccessToken());
            params.put("gatewayId", gatewayConf.getGatewayId());
            params.put("gatewayIp", gatewayConf.getGatewayIp());
            params.put("gatewayMac", gatewayConf.getGatewayMac());
            params.put("gatewayCPU", gatewayConf.getGatewayCPU());
            params.put("gatewayMem", gatewayConf.getGatewayMem());
            params.put("gatewayHardDisk", gatewayConf.getGatewayHardDisk());
            params.put("gatewayMac", null == gatewayConf.getGatewayMac() ? "无" : gatewayConf.getGatewayMac());
            params.put("gatewayCPU", null == gatewayConf.getGatewayCPU() ? "无" : gatewayConf.getGatewayCPU());
            params.put("gatewayMem", null == gatewayConf.getGatewayMem() ? "无" : gatewayConf.getGatewayMem());
            params.put("gatewayHardDisk", null == gatewayConf.getGatewayHardDisk() ? "无" : gatewayConf.getGatewayHardDisk());
            params.put("timestamp", System.currentTimeMillis() + "");
            String sign = getSign(params, gatewayConf.getPrivateKey());
            String sign = getSign(params, gatewayConf);
            params.put("sign", sign);
            String url = gatewayConf.getApiUrl() + "reserver/api/iot/equipment/heartbeat";
@@ -162,47 +182,62 @@
    }
    public String getSign(Map<String, String> parames, String priKey) {
        //参数拼接
        String msg = "";
        parames = sortMapKey(parames);
        for (Map.Entry<String, String> param : parames.entrySet()) {
            msg += param.getKey() + "=" + param.getValue() + "&";
        }
        msg = msg.substring(0, msg.length() - 1);
    @Override
    public void pushDeviceStatus(GatewayConf gatewayConf) {
        log.debug("------待加密信息-----{}", msg);
        //获取设备列表
        Collection<GatewayDevice> list = GatewayUtils.allCacheDevice();
        if (null == list || list.isEmpty()) {
            log.info("--------系统未获取到当前系统设备列表,不执行状态推送-----");
            return;
        }
        //封装设备报文信息
        DeviceStatusData statusData;
        String messageInfo;
        String topic = ScConstant.TOPIC_EQUIPMENT_STATUS;
        topic = topic.replace("{kqdm}", gatewayConf.getKqdm());
        for (GatewayDevice device : list) {
            //如果设备没有配置productId直接跳过
            if (StringUtils.isEmpty(device.getProductId())) continue;
            statusData = new DeviceStatusData();
            statusData.setMessageId(ContextUtil.getUUID());
            statusData.setApISource(ScConstant.API_SOURCE_TARGET_EQUIPMENT_STATUS);
            statusData.setGatewayId(gatewayConf.getGatewayId());
            statusData.setGatewayIp(gatewayConf.getGatewayIp());
            statusData.setProductId(device.getProductId());
            statusData.setEquipId(device.getDeviceId());
            statusData.setReportTime(DateFormatUtils.format(new Date(), "yyyy-MM-dd hh:mm:ss"));
            statusData.setMemo("FZZY");
            //针对粮情设备
            if (GatewayDeviceType.TYPE_07.getCode().equals(device.getType())) {
                if (Constant.YN_N.equals(device.getStatus())) statusData.setStatus(0);
            }
            messageInfo = JSONObject.toJSONString(statusData);
            //推送设备状态
            kafkaDeviceReportService.publishWithTopic(messageInfo, topic);
        }
    }
    public String getSign(Map<String, String> parames, GatewayConf gatewayConf) throws Exception {
        //参数调整
        String signContent = OpenApiSignatureUtils.getSignContent(parames);
        log.debug("------待加密信息-----{}", signContent);
        //MD5加密
        String md5sign = MyMD5Util.getMD5(msg);
        log.debug("------md5加密-----{}", md5sign);
        String md5sign = OpenApiSignatureUtils.getMd5Content(signContent, charset);
        //RSA加密
        String result = GatewayRSAUtils.encryptByPrivate(md5sign, priKey);
        log.debug("------RSA加密-----{}", result);
        String singValue = OpenApiSignatureUtils.doSignByHex(gatewayConf.getGatewayId(), md5sign, charset, gatewayConf.getPublicKey(), gatewayConf.getPrivateKey());
        log.debug("------RSA加密签名-----{}", singValue);
        return result;
    }
    public static String getSign2(Map<String, String> parames, String priKey) {
        //参数拼接
        String msg = "";
        parames = sortMapKey(parames);
        for (Map.Entry<String, String> param : parames.entrySet()) {
            msg += param.getKey() + "=" + param.getValue() + "&";
        }
        msg = msg.substring(0, msg.length() - 1);
        log.debug("------待加密信息-----{}", msg);
        //MD5加密
        String md5sign = MyMD5Util.getMD5(msg);
        log.debug("------md5加密-----{}", md5sign);
        //RSA加密
        String result = GatewayRSAUtils.encryptByPrivate(md5sign, priKey);
        log.debug("------RSA加密-----{}", result);
        return result;
        return singValue;
    }
    /**
@@ -214,56 +249,8 @@
    }
    private void updateAuthToken(GatewayConf conf) {
        gatewayConfService.updateCache(conf);
    }
    private static Map<String, String> sortMapKey(Map<String, String> map){
        if(map == null || map.isEmpty()){
            return  null;
        }
        Map<String, String> sortMap = new TreeMap<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        sortMap.putAll(map);
        return sortMap;
    }
    public static void main(String[] args) throws UnsupportedEncodingException {
        //网关心跳接口
//        Map<String, String> params = new HashMap<>();
//        //params.put("token", "");
//        params.put("gatewayId", "6e3d92ff71b911eea5e50250f2000002");
//        params.put("gatewayIp", "123");
//        params.put("gatewayMac", "123");
//        params.put("gatewayCPU","123");
//        params.put("gatewayMem", "123");
//        params.put("gatewayHardDisk", "123");
//        params.put("timestamp", "2023-10-31 12:12:12");
//        String sign = getSign2(params,"MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA0lg35sJGRyUFEDzt\np9pWvc0JD+0+SmiZIgMbUaEM5gqBsvUJ9LnzB0rpMTbuqAxAFbUH1Nw4qXdJVnKS\nRYfPgQIDAQABAkBPkxIq2Uou9gFRYEtkGcSA70VDYjQTgDiWVmiKXAv+JkEJmOno\\nMrHYQGAiP0q4xW66F+CLNCrGPVJns2ywMxwxAiEA/vyNX5M0/t+RHAxpMp484i9T\nb5Qf+HvepOV3c0UGZx0CIQDTLj4+qgoXGOLCM9/dzVJZ04VIjK6u546z22hXFWgI\ntQIhAMWFP8JMlx3kc1UF7Cuw1jrkLD7fwJBM7CBSPODHFHmlAiEAhv4Hcf02B/+z\nbBrG3rzSCHOKvo6XV1zTvqrhLtGTOAUCIGmoaIDgTuS0ZF71+c9mYvPVNL0T02GQ\nE8Y3ExreQphx");
//        params.put("sign", sign);
//
//        System.out.println(sign);
        byte[] encryptedData = GatewayRSAUtils.decryptBase64("yx7jNj9DGS7AkH/sXo5IrwaGNCSUnAZFmjXwWovMBfvYGVQur1RELXUu4fqIMZZ/ck6CAA3ESOJCS+aCD0aVdA==");
        StringBuilder hexString = new StringBuilder();
        for (byte b : encryptedData) {
            String hex = Integer.toHexString(0xFF & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        String hexStringResult = hexString.toString();
        System.out.println(hexStringResult);
        System.out.println(BytesUtil.bytesToString(GatewayRSAUtils.decryptBase64("mgtJOOn5iZBvmQI3hzvaw2J4BiZUcXhLTsgLk8++Ig2iIZcPaky7V+ylkA+BAYxIBS5ovHXjRo4w26TTEq9k7Q==")));
    }
}
src/main/java/com/fzzy/gateway/hx2023/service/HxGatewayRemoteServiceImpl2.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,205 @@
package com.fzzy.gateway.hx2023.service;
import com.alibaba.fastjson2.JSONObject;
import com.fzzy.api.data.PushProtocol;
import com.fzzy.api.view.repository.ApiLogRep;
import com.fzzy.gateway.api.GatewayRemoteService;
import com.fzzy.gateway.data.BaseResp;
import com.fzzy.gateway.entity.GatewayConf;
import com.fzzy.gateway.hx2023.data.CloudResp;
import com.fzzy.gateway.hx2023.util.OpenApiSignatureUtils;
import com.fzzy.gateway.service.GatewayConfService;
import com.fzzy.gateway.util.GatewayHttpUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Data
@Component
public class HxGatewayRemoteServiceImpl2 implements GatewayRemoteService {
    String charset = "utf-8";
    @Resource
    private ApiLogRep apiLogRep;
    @Resource
    private GatewayConfService gatewayConfService;
    @Override
    public String getProtocol() {
        //return PushProtocol.GATEWAY_SC_2023.getCode();
        return "GATEWAY_SC_2023-暂停使用";
    }
    @Override
    public void init(GatewayConf gatewayConf) {
        try {
            if (StringUtils.isEmpty(gatewayConf.getApiUrl())) {
                return;
            }
            //获取公私钥接口
            Map<String, String> params = new HashMap<>();
            params.put("appId", gatewayConf.getGatewayId());
            String url = gatewayConf.getApiUrl() + "reserver/api/key/apply";
            String jsonStr = GatewayHttpUtil.doGet(url, params);
            log.info("---获取公私钥接口-返回---{}", jsonStr);
            CloudResp respKey = JSONObject.parseObject(jsonStr, CloudResp.class);
            if (BaseResp.CODE_200 == respKey.getCode()) {
                JSONObject object = respKey.getData();
                String pubKey = (String) object.get("pubKey");
                String priKey = (String) object.get("priKey");
                gatewayConf.setPublicKey(pubKey);
                gatewayConf.setPrivateKey(priKey);
            }
            //获取 AccessToken æŽ¥å£
            String sign = getSign(params, gatewayConf);
            params.put("sign", sign);
            url = gatewayConf.getApiUrl() + "reserver/api/token/apply";
            jsonStr = GatewayHttpUtil.doGet(url, params);
            log.info("---获取AccessToken接口-返回---{}", jsonStr);
            CloudResp respToken = JSONObject.parseObject(jsonStr, CloudResp.class);
            if (BaseResp.CODE_200 == respToken.getCode()) {
                JSONObject object = respKey.getData();
                if (null != object) {
                    String token = (String) object.get("token");
                    gatewayConf.setAccessToken(token);
                }
            }
            //更新缓存
            updateAuthToken(gatewayConf);
        } catch (Exception e) {
            log.error("------初始化失败-----{}", e);
        }
    }
    @Override
    public void heartbeat(GatewayConf gatewayConf) {
        log.info("------------定时心跳执行---------{}", gatewayConf.getKqmc());
        try {
            if (StringUtils.isEmpty(gatewayConf.getApiUrl())) {
                return;
            }
            gatewayConf = getCacheConf(gatewayConf.getKqdm());
            //网关心跳接口
            Map<String, String> params = new HashMap<>();
            params.put("token", gatewayConf.getAccessToken());
            params.put("gatewayId", gatewayConf.getGatewayId());
            params.put("gatewayIp", gatewayConf.getGatewayIp());
            params.put("gatewayMac", gatewayConf.getGatewayMac());
            params.put("heartbeat", "1");
            params.put("timestamp", System.currentTimeMillis() + "");
            //获取签名信息
            String sign = getSign(params, gatewayConf);
            params.put("sign", sign);
            String url = gatewayConf.getApiUrl() + "reserver/api/iot/equipment/heartbeat";
            String jsonStr = GatewayHttpUtil.doGet(url, params);
            log.info("---网关心跳接口-返回---{}", jsonStr);
        } catch (Exception e) {
            log.error("------网关心跳接口--执行失败-----{}", e);
        }
    }
    @Override
    public void pushInfo(GatewayConf gatewayConf) {
        try {
            if (StringUtils.isEmpty(gatewayConf.getApiUrl())) {
                return;
            }
            gatewayConf = getCacheConf(gatewayConf.getKqdm());
            //网关心跳接口
            Map<String, String> params = new HashMap<>();
            params.put("token", gatewayConf.getAccessToken());
            params.put("gatewayId", gatewayConf.getGatewayId());
            params.put("gatewayIp", gatewayConf.getGatewayIp());
            params.put("gatewayMac", gatewayConf.getGatewayMac());
            params.put("gatewayCPU", gatewayConf.getGatewayCPU());
            params.put("gatewayMem", gatewayConf.getGatewayMem());
            params.put("gatewayHardDisk", gatewayConf.getGatewayHardDisk());
            params.put("timestamp", System.currentTimeMillis() + "");
            String sign = getSign(params, gatewayConf);
            params.put("sign", sign);
            String url = gatewayConf.getApiUrl() + "reserver/api/iot/equipment/heartbeat";
            String jsonStr = GatewayHttpUtil.doGet(url, params);
            log.info("---推送网关信息-返回---{}", jsonStr);
        } catch (Exception e) {
            log.error("------推送网关信息--执行失败-----{}", e);
        }
    }
    @Override
    public void pushDeviceStatus(GatewayConf gatewayConf) {
    }
    public String getSign(Map<String, String> parames, GatewayConf gatewayConf) throws Exception {
        //参数调整
        String signContent = OpenApiSignatureUtils.getSignContent(parames);
        log.debug("------待加密信息-----{}", signContent);
        //MD5加密
        String md5sign = OpenApiSignatureUtils.getMd5Content(signContent, charset);
        //RSA加密
        String singValue = OpenApiSignatureUtils.doSignByHex(gatewayConf.getGatewayId(), md5sign, charset, gatewayConf.getPublicKey(), gatewayConf.getPrivateKey());
        log.debug("------RSA加密签名-----{}", singValue);
        return singValue;
    }
    /**
     * @param kqdm
     * @return
     */
    public GatewayConf getCacheConf(String kqdm) {
        return gatewayConfService.getCacheConf(kqdm);
    }
    private void updateAuthToken(GatewayConf conf) {
        gatewayConfService.updateCache(conf);
    }
}
src/main/java/com/fzzy/gateway/hx2023/util/Base64Utils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,275 @@
package com.fzzy.gateway.hx2023.util;
/**
 * Base64Utils
 */
public class Base64Utils {
    static private final int     BASELENGTH           = 128;
    static private final int     LOOKUPLENGTH         = 64;
    static private final int     TWENTYFOURBITGROUP   = 24;
    static private final int     EIGHTBIT             = 8;
    static private final int     SIXTEENBIT           = 16;
    static private final int     FOURBYTE             = 4;
    static private final int     SIGN                 = -128;
    static private final char    PAD                  = '=';
    static private final boolean fDebug               = false;
    static final private byte[]  base64Alphabet       = new byte[BASELENGTH];
    static final private char[]  lookUpBase64Alphabet = new char[LOOKUPLENGTH];
    static {
        for (int i = 0; i < BASELENGTH; ++i) {
            base64Alphabet[i] = -1;
        }
        for (int i = 'Z'; i >= 'A'; i--) {
            base64Alphabet[i] = (byte) (i - 'A');
        }
        for (int i = 'z'; i >= 'a'; i--) {
            base64Alphabet[i] = (byte) (i - 'a' + 26);
        }
        for (int i = '9'; i >= '0'; i--) {
            base64Alphabet[i] = (byte) (i - '0' + 52);
        }
        base64Alphabet['+'] = 62;
        base64Alphabet['/'] = 63;
        for (int i = 0; i <= 25; i++) {
            lookUpBase64Alphabet[i] = (char) ('A' + i);
        }
        for (int i = 26, j = 0; i <= 51; i++, j++) {
            lookUpBase64Alphabet[i] = (char) ('a' + j);
        }
        for (int i = 52, j = 0; i <= 61; i++, j++) {
            lookUpBase64Alphabet[i] = (char) ('0' + j);
        }
        lookUpBase64Alphabet[62] = '+';
        lookUpBase64Alphabet[63] = '/';
    }
    private static boolean isWhiteSpace(char octect) {
        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
    }
    private static boolean isPad(char octect) {
        return (octect == PAD);
    }
    private static boolean isData(char octect) {
        return (octect < BASELENGTH && base64Alphabet[octect] != -1);
    }
    /**
     * Encodes hex octects into Base64
     *
     * @param binaryData Array containing binaryData
     * @return Encoded Base64 array
     */
    public static String encode(byte[] binaryData) {
        if (binaryData == null) {
            return null;
        }
        int lengthDataBits = binaryData.length * EIGHTBIT;
        if (lengthDataBits == 0) {
            return "";
        }
        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
        int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
        char[] encodedData = null;
        encodedData = new char[numberQuartet * 4];
        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
        int encodedIndex = 0;
        int dataIndex = 0;
        if (fDebug) {
            System.out.println("number of triplets = " + numberTriplets);
        }
        for (int i = 0; i < numberTriplets; i++) {
            b1 = binaryData[dataIndex++];
            b2 = binaryData[dataIndex++];
            b3 = binaryData[dataIndex++];
            if (fDebug) {
                System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
            }
            l = (byte) (b2 & 0x0f);
            k = (byte) (b1 & 0x03);
            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
            byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
            if (fDebug) {
                System.out.println("val2 = " + val2);
                System.out.println("k4   = " + (k << 4));
                System.out.println("vak  = " + (val2 | (k << 4)));
            }
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
        }
        // form integral number of 6-bit groups
        if (fewerThan24bits == EIGHTBIT) {
            b1 = binaryData[dataIndex];
            k = (byte) (b1 & 0x03);
            if (fDebug) {
                System.out.println("b1=" + b1);
                System.out.println("b1<<2 = " + (b1 >> 2));
            }
            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
            encodedData[encodedIndex++] = PAD;
            encodedData[encodedIndex++] = PAD;
        } else if (fewerThan24bits == SIXTEENBIT) {
            b1 = binaryData[dataIndex];
            b2 = binaryData[dataIndex + 1];
            l = (byte) (b2 & 0x0f);
            k = (byte) (b1 & 0x03);
            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
            encodedData[encodedIndex++] = PAD;
        }
        return new String(encodedData);
    }
    /**
     * Decodes Base64 data into octects
     *
     * @param encoded string containing Base64 data
     * @return Array containind decoded data.
     */
    public static byte[] decode(String encoded) {
        if (encoded == null) {
            return null;
        }
        char[] base64Data = encoded.toCharArray();
        // remove white spaces
        int len = removeWhiteSpace(base64Data);
        if (len % FOURBYTE != 0) {
            return null;//should be divisible by four
        }
        int numberQuadruple = (len / FOURBYTE);
        if (numberQuadruple == 0) {
            return new byte[0];
        }
        byte[] decodedData = null;
        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
        char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
        int i = 0;
        int encodedIndex = 0;
        int dataIndex = 0;
        decodedData = new byte[(numberQuadruple) * 3];
        for (; i < numberQuadruple - 1; i++) {
            if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
                    || !isData((d3 = base64Data[dataIndex++]))
                    || !isData((d4 = base64Data[dataIndex++]))) {
                return null;
            }//if found "no data" just return null
            b1 = base64Alphabet[d1];
            b2 = base64Alphabet[d2];
            b3 = base64Alphabet[d3];
            b4 = base64Alphabet[d4];
            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
        }
        if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
            return null;//if found "no data" just return null
        }
        b1 = base64Alphabet[d1];
        b2 = base64Alphabet[d2];
        d3 = base64Data[dataIndex++];
        d4 = base64Data[dataIndex++];
        if (!isData((d3)) || !isData((d4))) {//Check if they are PAD characters
            if (isPad(d3) && isPad(d4)) {
                if ((b2 & 0xf) != 0)//last 4 bits should be zero
                {
                    return null;
                }
                byte[] tmp = new byte[i * 3 + 1];
                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
                tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
                return tmp;
            } else if (!isPad(d3) && isPad(d4)) {
                b3 = base64Alphabet[d3];
                if ((b3 & 0x3) != 0)//last 2 bits should be zero
                {
                    return null;
                }
                byte[] tmp = new byte[i * 3 + 2];
                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
                tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
                tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
                return tmp;
            } else {
                return null;
            }
        } else { //No PAD e.g 3cQl
            b3 = base64Alphabet[d3];
            b4 = base64Alphabet[d4];
            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
        }
        return decodedData;
    }
    /**
     * remove WhiteSpace from MIME containing encoded Base64 data.
     *
     * @param data  the byte array of base64 data (with WS)
     * @return      the new length
     */
    private static int removeWhiteSpace(char[] data) {
        if (data == null) {
            return 0;
        }
        // count characters that's not whitespace
        int newSize = 0;
        int len = data.length;
        for (int i = 0; i < len; i++) {
            if (!isWhiteSpace(data[i])) {
                data[newSize++] = data[i];
            }
        }
        return newSize;
    }
}
src/main/java/com/fzzy/gateway/hx2023/util/OpenApiRsaSigner.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,283 @@
package com.fzzy.gateway.hx2023.util;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.Data;
/**
 * RSA签名验签类
 *
 */
@Slf4j
@Data
public class OpenApiRsaSigner {
    /**
     * åŽç»­ç”¨äºŽç¼“存公钥和私钥
     */
    private static Map<String, OpenApiRsaSigner> signerMap = new HashMap<>();
    private PublicKey publicKey;
    private PrivateKey privateKey;
    /**
     * å­—节数据转字符串专用集合
     */
    private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    private OpenApiRsaSigner(PublicKey publicKey, PrivateKey privateKey) {
        this.publicKey = publicKey;
        this.privateKey = privateKey;
    }
    public static OpenApiRsaSigner initSigner(String publicKey, String privateKey) {
        try {
            PublicKey publicKeyObj = loadPublicKeyByStr(publicKey);
            PrivateKey privateKeyObj = loadPrivateKeyByStr(privateKey);
            return new OpenApiRsaSigner(publicKeyObj, privateKeyObj);
        }catch (Exception e) {
            log.error("initSigner(),exception happens.", e);
        }
        return null;
    }
    /**
     * ä»Žå­—符串中加载公钥
     *
     * @param publicKeyStr å…¬é’¥æ•°æ®å­—符串
     * @throws Exception åŠ è½½å…¬é’¥æ—¶äº§ç”Ÿçš„å¼‚å¸¸
     */
    public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr) throws Exception {
        try {
            byte[] buffer = Base64Utils.decode(publicKeyStr);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
            return (RSAPublicKey) keyFactory.generatePublic(keySpec);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此算法");
        } catch (InvalidKeySpecException e) {
            throw new Exception("公钥非法");
        } catch (NullPointerException e) {
            throw new Exception("公钥数据为空");
        }
    }
    /**
     * @param privateKeyStr
     * @return
     * @throws Exception
     */
    public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr) throws Exception {
        try {
            byte[] buffer = Base64Utils.decode(privateKeyStr);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此算法");
        } catch (InvalidKeySpecException e) {
            throw new Exception("私钥非法");
        } catch (NullPointerException e) {
            throw new Exception("私钥数据为空");
        }
    }
    /**
     * å…¬é’¥åŠ å¯†è¿‡ç¨‹
     *
     * @param publicKey     å…¬é’¥
     * @param plainTextData æ˜Žæ–‡æ•°æ®
     * @return
     * @throws Exception åŠ å¯†è¿‡ç¨‹ä¸­çš„å¼‚å¸¸ä¿¡æ¯
     */
    public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception {
        if (publicKey == null) {
            throw new Exception("加密公钥为空, è¯·è®¾ç½®");
        }
        Cipher cipher = null;
        try {
            // ä½¿ç”¨é»˜è®¤RSA
            cipher = Cipher.getInstance("RSA");
            // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] output = cipher.doFinal(plainTextData);
            return output;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此加密算法");
        } catch (NoSuchPaddingException e) {
            log.error("exception happens.", e);
            return null;
        } catch (InvalidKeyException e) {
            throw new Exception("加密公钥非法,请检查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("明文长度非法");
        } catch (BadPaddingException e) {
            throw new Exception("明文数据已损坏");
        }
    }
    /**
     * ç§é’¥åŠ å¯†è¿‡ç¨‹
     *
     * @param privateKey    ç§é’¥
     * @param plainTextData æ˜Žæ–‡æ•°æ®
     * @return
     * @throws Exception åŠ å¯†è¿‡ç¨‹ä¸­çš„å¼‚å¸¸ä¿¡æ¯
     */
    public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData) throws Exception {
        if (privateKey == null) {
            throw new Exception("加密私钥为空, è¯·è®¾ç½®");
        }
        Cipher cipher = null;
        try {
            // ä½¿ç”¨é»˜è®¤RSA
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            byte[] output = cipher.doFinal(plainTextData);
            return output;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此加密算法");
        } catch (NoSuchPaddingException e) {
            log.error("exception happens.", e);
            return null;
        } catch (InvalidKeyException e) {
            throw new Exception("加密私钥非法,请检查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("明文长度非法");
        } catch (BadPaddingException e) {
            throw new Exception("明文数据已损坏");
        }
    }
    /**
     * ç§é’¥è§£å¯†è¿‡ç¨‹
     *
     * @param privateKey ç§é’¥
     * @param cipherData å¯†æ–‡æ•°æ®
     * @return æ˜Žæ–‡
     * @throws Exception è§£å¯†è¿‡ç¨‹ä¸­çš„异常信息
     */
    public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception {
        if (privateKey == null) {
            throw new Exception("解密私钥为空, è¯·è®¾ç½®");
        }
        if (cipherData == null) {
            return null;
        }
        Cipher cipher = null;
        try {
            // ä½¿ç”¨é»˜è®¤RSA
            cipher = Cipher.getInstance("RSA");
            // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] output = cipher.doFinal(cipherData);
            return output;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此解密算法");
        } catch (NoSuchPaddingException e) {
            log.error("exception happens.", e);
            return null;
        } catch (InvalidKeyException e) {
            throw new Exception("解密私钥非法,请检查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("密文长度非法");
        } catch (BadPaddingException e) {
            throw new Exception("密文数据已损坏");
        }
    }
    /**
     * å…¬é’¥è§£å¯†è¿‡ç¨‹
     *
     * @param publicKey  å…¬é’¥
     * @param cipherData å¯†æ–‡æ•°æ®
     * @return æ˜Žæ–‡
     * @throws Exception è§£å¯†è¿‡ç¨‹ä¸­çš„异常信息
     */
    public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData) throws Exception {
        if (publicKey == null) {
            throw new Exception("解密公钥为空, è¯·è®¾ç½®");
        }
        Cipher cipher = null;
        try {
            // ä½¿ç”¨é»˜è®¤RSA
            cipher = Cipher.getInstance("RSA");
            // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            byte[] output = cipher.doFinal(cipherData);
            return output;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此解密算法");
        } catch (NoSuchPaddingException e) {
            log.error("exception happens.", e);
            return null;
        } catch (InvalidKeyException e) {
            throw new Exception("解密公钥非法,请检查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("密文长度非法");
        } catch (BadPaddingException e) {
            throw new Exception("密文数据已损坏");
        }
    }
    public static boolean verify(String content, String sign, RSAPrivateKey privateKey) throws Exception {
        byte[] singBytes = encrypt(privateKey, content.getBytes());
        return sign.equals(new String(singBytes));
    }
    /**
     * å­—节数据转十六进制字符串
     *
     * @param data è¾“入数据
     * @return åå…­è¿›åˆ¶å†…容
     */
    public static String byteArrayToString(byte[] data) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < data.length; i++) {
            // å–出字节的高四位 ä½œä¸ºç´¢å¼•得到相应的十六进制标识符 æ³¨æ„æ— ç¬¦å·å³ç§»
            stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);
            // å–出字节的低四位 ä½œä¸ºç´¢å¼•得到相应的十六进制标识符
            stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
            if (i < data.length - 1) {
                stringBuilder.append(' ');
            }
        }
        return stringBuilder.toString();
    }
    public static OpenApiRsaSigner getInstance(String appId, String publicKey, String privateKey) {
        OpenApiRsaSigner signer = signerMap.get(appId);
        if (signer != null) {
            return signer;
        }
        try {
            signer = initSigner(publicKey, privateKey);
            if(signer != null){
                signerMap.put(appId, signer);
            }
        } catch (Exception e) {
            log.error("exception happens.", e);
        }
        return signerMap.get(appId);
    }
}
src/main/java/com/fzzy/gateway/hx2023/util/OpenApiSignatureUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,206 @@
package com.fzzy.gateway.hx2023.util;
import cn.hutool.crypto.digest.MD5;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.interfaces.RSAPrivateKey;
import java.util.*;
/**
 * ç­¾åå·¥å…·ç±»
 */
@Slf4j
@Data
public class OpenApiSignatureUtils {
    public static String getMd5Content(String content, String charset) {
        try {
            byte[] md5 = MD5.create().digest(content);
            return new String(md5, charset);
        } catch (UnsupportedEncodingException e) {
            log.error("getMd5Content(),exception happens.", e);
        }
        return null;
    }
    public static String getSignContent(final Map<String, String> sortedParams) {
        StringBuffer content = new StringBuffer();
        List<String> keys = new ArrayList(sortedParams.keySet());
        Collections.sort(keys);
        int index = 0;
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = sortedParams.get(key);
            if (key.equals("sign") || key.equals("sign_type")) {
                continue;
            }
            if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(value)) {
                content.append((index == 0 ? "" : "&") + key + "=" + value);
                index++;
            }
        }
        return content.toString();
    }
    public static String getSignContentWithQuotes(final Map<String, String> sortedParams) {
        StringBuffer content = new StringBuffer();
        List<String> keys = new ArrayList<String>(sortedParams.keySet());
        Collections.sort(keys);
        int index = 0;
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = sortedParams.get(key);
            if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(value)) {
                content.append((index == 0 ? "" : "&") + key + "=\"" + value + "\"");
                index++;
            }
        }
        return content.toString();
    }
    public static boolean doCheckV1(String appId, Map<String, String> params, String charset, String publicKey, String privateKye) throws Exception {
        String sign = params.get("sign");
        String content = getSignCheckContentWithoutSign(params);
        return doRsaCheckContent(appId, content, sign, charset, publicKey, privateKye);
    }
    public static String doSignByBase64(String appId, String content, String charset, String publicKey, String privateKye) throws RuntimeException {
        try {
            byte[] signData = OpenApiRsaSigner.encrypt((RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey(), content.getBytes(charset));
            //return new String(signData, charset);
            return new String(Base64.encodeBase64(signData), StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("key=" + appId + ";content=" + content + ";charset=" + charset, e);
        }
    }
    public static String doSignByHex(String appId, String content, String charset, String publicKey, String privateKye) throws RuntimeException {
        try {
            byte[] signData = OpenApiRsaSigner.encrypt((RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey(), content.getBytes(charset));
            //return new String(signData, charset);
            return new String(Hex.encodeHex(signData));
        } catch (Exception e) {
            throw new RuntimeException("key=" + appId + ";content=" + content + ";charset=" + charset, e);
        }
    }
    public static String doSignByTranscode(String appId, String content, String charset, String publicKey, String privateKye) throws RuntimeException {
        try {
            byte[] signData = OpenApiRsaSigner.encrypt((RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey(), content.getBytes(charset));
            return new String(signData, charset);
            //return new String(Base64.encodeBase64(signData), StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("key=" + appId + ";content=" + content + ";charset=" + charset, e);
        }
    }
    public static String getSignCheckContentWithoutSign(Map<String, String> params) {
        if (params == null) {
            return null;
        }
        params.remove("sign");
        params.remove("sign_type");
        StringBuffer content = new StringBuffer();
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            content.append((i == 0 ? "" : "&") + key + "=" + value);
        }
        return content.toString();
    }
    public static boolean doRsaCheckContent(String appId, String content, String sign,
                                            String charset, String publicKey, String privateKye) throws RuntimeException {
        try {
            RSAPrivateKey privateKey = (RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey();
            return OpenApiRsaSigner.verify(content, sign, privateKey);
        } catch (Exception e) {
            throw new RuntimeException("key=" + appId + ";content=" + content + ";sign=" + sign + ";charset="
                    + charset, e);
        }
    }
    public static boolean doCheckByBase64(String appId, String content, String sign,
                                          String charset, String publicKey, String privateKye) throws RuntimeException {
        try {
            RSAPrivateKey privateKey = (RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey();
            return OpenApiRsaSigner.verify(content, new String(Base64.decodeBase64(sign), StandardCharsets.UTF_8), privateKey);
        } catch (Exception e) {
            throw new RuntimeException("key=" + appId + ";content=" + content + ";sign=" + sign + ";charset="
                    + charset, e);
        }
    }
    public static boolean doCheckByHex(String appId, String content, String sign,
                                       String charset, String publicKey, String privateKye) throws RuntimeException {
        try {
            RSAPrivateKey privateKey = (RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey();
            return OpenApiRsaSigner.verify(content, new String(Hex.decodeHex(sign.toCharArray())), privateKey);
        } catch (Exception e) {
            throw new RuntimeException("key=" + appId + ";content=" + content + ";sign=" + sign + ";charset="
                    + charset, e);
        }
    }
    public static boolean doCheckByTranscode(String appId, String content, String sign,
                                             String charset, String publicKey, String privateKye) throws RuntimeException {
        try {
            RSAPrivateKey privateKey = (RSAPrivateKey) OpenApiRsaSigner.getInstance(appId, publicKey, privateKye).getPrivateKey();
            return OpenApiRsaSigner.verify(content, sign, privateKey);
        } catch (Exception e) {
            throw new RuntimeException("key=" + appId + ";content=" + content + ";sign=" + sign + ";charset="
                    + charset, e);
        }
    }
    /**
     * èŽ·å–è¯·æ±‚å‚æ•°
     *
     * @param request
     * @return
     */
    public static Map<String, String> getParameterMap(HttpServletRequest request) {
        Enumeration<String> parameters = request.getParameterNames();
        if (parameters == null) {
            return new HashMap<>();
        }
        HashMap resultMap = new HashMap<>();
        while (parameters.hasMoreElements()) {
            String key = parameters.nextElement();
            String value = request.getParameter(key);
            resultMap.put(key, value);
        }
        return resultMap;
    }
    /**
     * æµ‹è¯•逻辑
     *
     * @param args
     * @throws UnsupportedEncodingException
     */
    public static void testSign(String[] args) throws UnsupportedEncodingException {
        Map<String, String> sortedParams = new HashMap<String, String>();
        sortedParams.put("appId", "6e3d896b71b911eea5e50250f2000002");
//        sortedParams.put("method", "test");
//        sortedParams.put("format", "json");
//        sortedParams.put("charset", "utf-8");
//        sortedParams.put("sign_type", "RSA");
//        sortedParams.put("timestamp", "2019-01-01 00:00:00");
//        sortedParams.put("version", "1.0");
//        sortedParams.put("biz_content", "{\"name\":\"张三\",\"age\":18}");
    }
}
src/main/java/com/fzzy/gateway/service/GatewayDeviceService.java
@@ -6,13 +6,9 @@
import com.fzzy.api.Constant;
import com.fzzy.api.data.ApiCommonDevice;
import com.fzzy.api.utils.ContextUtil;
import com.fzzy.async.fzzy40.Fzzy40CommonService;
import com.fzzy.gateway.GatewayUtils;
import com.fzzy.gateway.api.GatewayRemoteManager;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.gateway.service.repository.GatewayDeviceRep;
import com.fzzy.mqtt.MqttProviderConfig;
import com.fzzy.mqtt.MqttPublishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
@@ -20,6 +16,7 @@
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Slf4j
@@ -45,36 +42,20 @@
        List<GatewayDevice> result = new ArrayList<>();
        ApiCommonDevice apiCommonDevice;
        GatewayDevice cacheDevice;
        for (GatewayDevice device : list) {
            apiCommonDevice = Constant.getCommonDeviceCache(device.getDeviceSn());
            if (null != apiCommonDevice) {
                device.setIp(apiCommonDevice.getIp());
                device.setPort(apiCommonDevice.getPort());
                device.setStatus(apiCommonDevice.getStatus());
                device.setOnlineTime(apiCommonDevice.getOnlineTime());
            device.setStatus(Constant.YN_Y);
            cacheDevice = GatewayUtils.getCacheByDeviceId(device.getDeviceId());
            if (null != cacheDevice) {
                device.setIp(cacheDevice.getIp());
                device.setPort(cacheDevice.getPort());
                device.setStatus(cacheDevice.getStatus());
                device.setOnlineTime(cacheDevice.getOnlineTime());
            }
            result.add(device);
        }
        return result;
    }
//    /**
//     * gatewayDeviceService#getQuery
//     *
//     * @return
//     */
//    @DataProvider
//    public GateWayTestParam getQuery() {
//        GateWayTestParam param = new GateWayTestParam();
//        param.setDayTime(new Date());
//        param.setCarNumber("川A12345");
//        param.setEnd(new Date());
//        param.setStart(new Date());
//        param.setWeight(25000.00);
//        return param;
//    }
    /**
     * gatewayDeviceService#updateSave
@@ -134,4 +115,37 @@
        log.info("-----------test-------------------");
        return "SUCCESS";
    }
    /**
     * æ ¹æ®å®žé™…通讯分机设置,当前分机在线
     *
     * @param commonDevice å®žé™…通讯设备
     */
    public void onlineByCommonDevice(ApiCommonDevice commonDevice) {
        List<GatewayDevice> list = GatewayUtils.getCacheByDeviceSn2(commonDevice.getSn());
        if (null == list || list.isEmpty()) return;
        for (GatewayDevice device : list) {
            device.setIp(commonDevice.getIp());
            device.setPort(commonDevice.getPort());
            device.setOnlineTime(new Date());
            device.setStatus(Constant.YN_Y);
            GatewayUtils.add2Cache(device);
        }
    }
    public void OfflineByCommonDevice(ApiCommonDevice commonDevice) {
        List<GatewayDevice> list = GatewayUtils.getCacheByDeviceSn2(commonDevice.getSn());
        if (null == list || list.isEmpty()) return;
        for (GatewayDevice device : list) {
            device.setIp(commonDevice.getIp());
            device.setPort(commonDevice.getPort());
            //device.setOnlineTime(new Date());
            device.setStatus(Constant.YN_N);
            GatewayUtils.add2Cache(device);
        }
    }
}
src/main/java/com/fzzy/gateway/util/GatewayHttpUtil.java
@@ -47,7 +47,7 @@
            }
            HttpGet method = new HttpGet(getUrl);
            method.setHeader("Accept", "application/json");
            method.setHeader("charset", "UTF-8");
            method.setHeader("charset", "utf-8");
            response = client.execute(method);
//            response.setHeader("Accept", "application/json");
src/main/java/com/fzzy/gateway/util/GatewayRSAUtils.java
ÎļþÒÑɾ³ý
src/main/java/com/fzzy/protocol/fzzy/analysis/AnalysisSystem.java
@@ -4,6 +4,7 @@
import com.fzzy.api.data.ApiCommonDevice;
import com.fzzy.gateway.GatewayUtils;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.gateway.service.GatewayDeviceService;
import com.fzzy.protocol.fzzy.builder.ObjectCommandBuilder;
import com.fzzy.protocol.fzzy.builder.SimpleCommandBuilder;
import com.fzzy.protocol.fzzy.cmd.BaseRemoteImpl;
@@ -15,6 +16,7 @@
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
/**
@@ -25,6 +27,10 @@
public class AnalysisSystem extends BaseRemoteImpl {
    public static final String BEAN_ID = "fzzy.analysisSystem";
    @Resource
    private GatewayDeviceService gatewayDeviceService;
    public void analysis1001(ReMessage reMessage) {
@@ -39,8 +45,12 @@
        device.setSn(reMessage.getSn());
        device.setId(reMessage.getIedId());
        device.setOnlineTime(new Date());
        device.setCode("SUCCESS");
        Constant.updateCache(device);
        //更新设备在线
        gatewayDeviceService.onlineByCommonDevice(device);
        //返回当前系统时间
        Response1001 response = new Response1001();
src/main/java/com/fzzy/protocol/fzzy/server/SessionListener.java
@@ -1,11 +1,19 @@
package com.fzzy.protocol.fzzy.server;
import com.fzzy.api.Constant;
import com.fzzy.api.data.ApiCommonDevice;
import com.fzzy.api.utils.SpringUtil;
import com.fzzy.gateway.service.GatewayDeviceService;
import com.ld.io.api.IoSession;
import com.ld.io.api.IoSessionListener;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
@Slf4j
public class SessionListener implements IoSessionListener {
    private GatewayDeviceService gatewayDeviceService;
    @Override
    public void onCreate(IoSession session) {
@@ -20,5 +28,18 @@
    @Override
    public void onDestroy(IoSession session) {
        log.info("----FZZY-控制个协议有设备离线-----IP={},PORT={}", session.getAddress(), session.getPort());
        //设置分机掉线
        ApiCommonDevice commonDevice = Constant.updateCacheOffline(session.getAddress(), session.getPort());
        if (null == commonDevice) return;
        if (null == gatewayDeviceService) {
            gatewayDeviceService = SpringUtil.getBean(GatewayDeviceService.class);
            gatewayDeviceService.OfflineByCommonDevice(commonDevice);
        }
    }
}
src/main/java/com/fzzy/protocol/sdkhk/common/LPRCallBask_V31.java
@@ -1,6 +1,7 @@
package com.fzzy.protocol.sdkhk.common;
import com.fzzy.api.data.GatewayDeviceType;
import com.fzzy.api.utils.SpringUtil;
import com.fzzy.gateway.GatewayUtils;
import com.fzzy.gateway.api.GatewayRemoteManager;
src/main/java/com/fzzy/protocol/weightyh/MessageConsumer.java
@@ -1,5 +1,6 @@
package com.fzzy.protocol.weightyh;
import com.fzzy.api.data.GatewayDeviceType;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.api.utils.SpringUtil;
import com.fzzy.gateway.GatewayUtils;
src/main/resources/application-dev.yml
@@ -75,6 +75,7 @@
      max-idle: 10
      min-idle: 0
      timeout: 6000
  kafka:
    bootstrap-servers: 103.203.217.42:9092
    security-protocol: SASL_PLAINTEXT
@@ -82,6 +83,7 @@
    sasl-jaas-config: org.apache.kafka.common.security.scram.ScramLoginModule required username=\"{username}\" password=\"{password}\";"
    sasl-username: sc001
    sasl-password: wCV0ISwmoKwbx1lpBKMW
    enabled: false
    producer:
      retries: 0
      acks: 1
src/main/resources/application-devGateway.yml
@@ -46,8 +46,10 @@
      max-idle: 10
      min-idle: 0
      timeout: 6000
  kafka:
    bootstrap-servers: 103.203.217.16:9092
    enabled: false
    producer:
      retries: 0
      acks: 1
src/main/resources/application-devGatewayCommon.yml
@@ -48,6 +48,7 @@
      timeout: 6000
  kafka:
    bootstrap-servers: 103.203.217.16:9092
    enabled: false
    producer:
      retries: 0
      acks: 1
src/main/resources/application-proGateway.yml
@@ -48,6 +48,7 @@
      timeout: 6000
  kafka:
    bootstrap-servers: 103.203.217.16:9092
    enabled: false
    producer:
      retries: 0
      acks: 1