From 511931e3a505d0ece2c65fbb2a5a2a60d1a78856 Mon Sep 17 00:00:00 2001 From: haozq <1611483981@qq.com> Date: Mon, 19 Aug 2024 16:42:02 +0800 Subject: [PATCH] =?UTF-8?q?websocket=20=E6=95=B0=E6=8D=AE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...BootNettyChannelInboundHandlerAdapter.java | 7 +- .../bonus/aqd/tcpservice/BootNettyServer.java | 15 +- .../bonus/aqd/tcpservice/HexStringUtil.java | 343 ++++++++++++++++++ .../bonus/aqd/tcpservice/SaveDataService.java | 45 ++- .../bonus/aqd/websocket/config/WsConfig.java | 2 + .../websocket/handle/AqdSocketHandler.java | 3 + src/main/resources/application.yml | 4 +- 7 files changed, 392 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/bonus/aqd/tcpservice/HexStringUtil.java diff --git a/src/main/java/com/bonus/aqd/tcpservice/BootNettyChannelInboundHandlerAdapter.java b/src/main/java/com/bonus/aqd/tcpservice/BootNettyChannelInboundHandlerAdapter.java index 39aa2ba..97d3c53 100644 --- a/src/main/java/com/bonus/aqd/tcpservice/BootNettyChannelInboundHandlerAdapter.java +++ b/src/main/java/com/bonus/aqd/tcpservice/BootNettyChannelInboundHandlerAdapter.java @@ -65,14 +65,13 @@ public class BootNettyChannelInboundHandlerAdapter extends ChannelInboundHandler byte[] bs = new byte[in.readableBytes()]; in.readBytes(bs); String order = ByteUtil.bytesToHexString(bs); - service.addDataInfo(order.trim()); //转成String String data =order; //替换掉 换行 和 空格 data = data.replaceAll("\r|\n", ""); //获取通道ID 并打印 String channelId = ctx.channel().id().toString(); - System.err.println("通道号---> " + channelId + "--->数据---> " + data); + // System.err.println("通道号---> " + channelId + "--->数据---> " + data); // 这里我将通道id作为code来使用,实际是需要msg里来摘取的客户端数据里的唯一值的 // 如果没有则创建 如果有,更新data值 BootNettyChannel b = BootNettyChannelCache.get("server:" + channelId); @@ -95,7 +94,7 @@ public class BootNettyChannelInboundHandlerAdapter extends ChannelInboundHandler // ctx.channel().writeAndFlush("你好"); // ctx.channel().flush(); //回写给客户端 - ctx.writeAndFlush(Unpooled.buffer().writeBytes(("55aa78865ccd000103000000000d").getBytes())); + ctx.writeAndFlush(Unpooled.buffer().writeBytes(("server:" + channelId).getBytes())); // netty的编码已经指定,因此可以不需要再次确认编码 // ctx.writeAndFlush(Unpooled.buffer().writeBytes(channelId.getBytes(CharsetUtil.UTF_8))); @@ -113,7 +112,7 @@ public class BootNettyChannelInboundHandlerAdapter extends ChannelInboundHandler */ @Override public void channelReadComplete(ChannelHandlerContext ctx) throws IOException { - System.out.println("channelReadComplete"); + // System.out.println("channelReadComplete"); ctx.flush(); } diff --git a/src/main/java/com/bonus/aqd/tcpservice/BootNettyServer.java b/src/main/java/com/bonus/aqd/tcpservice/BootNettyServer.java index 794df0a..ffb42a8 100644 --- a/src/main/java/com/bonus/aqd/tcpservice/BootNettyServer.java +++ b/src/main/java/com/bonus/aqd/tcpservice/BootNettyServer.java @@ -1,6 +1,7 @@ package com.bonus.aqd.tcpservice; import io.netty.bootstrap.ServerBootstrap; +import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; @@ -103,9 +104,17 @@ public class BootNettyServer { } public void sendMessage(String clientId, Object message) { BootNettyChannel bnc = BootNettyChannelCache.get("server:" + clientId); - if (bnc.getChannel() != null && bnc.getChannel().isActive()) { - System.err.println("发送了消息:" +message); - bnc.getContext().writeAndFlush( Unpooled.buffer().writeBytes((message.toString()).getBytes())); + + if (bnc!=null && bnc.getChannel() != null && bnc.getChannel().isActive()) { + System.err.println("发送了消息:" +message); + byte[] bytes= HexStringUtil.hexToByteArray(message.toString()); + ByteBuf buffer = Unpooled.buffer(bytes.length); + buffer.writeBytes(bytes); + // ByteBuf bufff = Unpooled.buffer(); + // bnc.getChannel().writeAndFlush(bufff); + bnc.getContext().writeAndFlush( Unpooled.buffer().writeBytes(bytes)); + }else{ + System.err.println("声光告警设备不在线:"); } } } diff --git a/src/main/java/com/bonus/aqd/tcpservice/HexStringUtil.java b/src/main/java/com/bonus/aqd/tcpservice/HexStringUtil.java new file mode 100644 index 0000000..df549e3 --- /dev/null +++ b/src/main/java/com/bonus/aqd/tcpservice/HexStringUtil.java @@ -0,0 +1,343 @@ +package com.bonus.aqd.tcpservice; + +import com.bonus.aqd.manager.common.util.StringHelper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 十六进制常用工具 + * + * @author CLS + * @since 1.0.0 + */ +@Slf4j +public class HexStringUtil { + + /** + * 将 英文,日文,中文转成十六进制 + * + * @param inputString + * @return + */ + public static String changeStringToHex(final String inputString) { + int changeLine = 1; + String s = "Convert a string to HEX/こんにちは/你好"; + if (inputString != null) { + s = inputString; + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + byte[] ba = s.substring(i, i + 1).getBytes(); + // & 0xFF for preventing minus + String tmpHex = Integer.toHexString(ba[0] & 0xFF); + + if (changeLine++ % 8 == 0) { + } + // Multiply byte according + if (ba.length == 2) { + tmpHex = Integer.toHexString(ba[1] & 0xff); +// System.out.print("0x" + tmpHex.toUpperCase()); +// System.out.print(" "); + if (changeLine++ % 8 == 0) { + } + } + + sb.append(tmpHex.toUpperCase()); + } + return sb.toString(); + } + + /** + * 16进制字符串转化为字节流数 + * + * @param inHex 要转16进制字节流数组的16进制字符 + * @return 16进制字节流数 + */ + public static byte[] hexToByteArray(String inHex) { + + int hexlen = inHex.length(); + byte[] result; + if (hexlen % 2 == 1) { + // 奇数 + hexlen++; + result = new byte[(hexlen / 2)]; + inHex = "0" + inHex; + } else { + // 偶数 + result = new byte[(hexlen / 2)]; + } + int j = 0; + for (int i = 0; i < hexlen; i += 2) { + result[j] = hexToByte(inHex.substring(i, i + 2)); + j++; + } + return result; + } + + + + /** + * 字节转换-->解决数据转换为负数的问题 + * @param datas + */ + public static String toStringOCR(byte[] datas){ + StringBuilder msg=new StringBuilder(); + int i=0; + for (int data:datas) { + if(data!=0){ + int num = data & 0xff; + String hexString = Integer.toHexString(num); + if(hexString.length()<2){ + hexString="0"+hexString; + } + if(i==0){ + msg.append(hexString); + }else{ + msg.append(" "+hexString); + } + }else{ + String hexString = Integer.toHexString(data); + if(hexString.length()<2){ + hexString="0"+hexString; + } + if(i==0){ + msg.append(hexString); + }else{ + msg.append(" "+hexString); + } + } + i++; + } + return msg.toString(); + } + + + public static List getData2(String msg){ + List list=new ArrayList(); + try { + if(StringHelper.isNotEmpty(msg)){ + String[] msr=msg.split(" "); + for (int i = 0; i 8){ + int j=i-8; + if(j%4==0){ + String data=msr[i-3]+msr[i-2]+msr[i-1]+msr[i-0]; + double b=hexToFloat2(data); + list.add(b); + } + } + } + } + + }catch (Exception e){ + log.error(e.toString(),e); + } + return list; + } + + + public static List getData3(String msg){ + List list=new ArrayList(); + try { + if(StringHelper.isNotEmpty(msg)){ + String[] msr=msg.split(" "); + for (int i = 0; i 8){ + int j=i-8; + if(j%4==0){ + String data=msr[i-3]+msr[i-2]+msr[i-1]+msr[i-0]; + double b=hexToFloat2(data); + list.add(b); + } + } + } + } + + }catch (Exception e){ + log.error(e.toString(),e); + } + return list; + } + + + + + /** + * 解析 浮点形数据转换 + * @param msg + * @return + */ + public static List getData(String msg){ + List list=new ArrayList(); + try{ + StringBuilder builder=new StringBuilder(); + if(StringHelper.isNotEmpty(msg)){ + String[] msr=msg.split(" "); + for (int i = 0; i 8){ + if(i%2==0){ + int num = Integer.parseInt(msr[i-1]+msr[i], 16); + double b= (double)num/10.0; + list.add(b); + } + }else{ + builder.append(msr[i]+" "); + } + } + } + // log.info("数据前缀==>"+builder); + }catch (Exception e){ + // log.info("数据解析异常==>"+msg); + log.error(e.toString(),e); + } + return list; + } + + /** + * 解析状态值 + * @return + */ + public static String getStateData(String msgStr) { + StringBuffer st=new StringBuffer(); + try{ + msgStr=msgStr.substring(26,msgStr.length()).trim();//去除多余的数据 + String[] datas=msgStr.split(" "); + for (int i = 0; i < datas.length; i++) {//数据转二进制 + String data=toTwoHex(datas[i]);//转2进制 + st.append(data); + } + + }catch (Exception e){ + log.error(e.toString(),e); + } + return st.toString(); + } + + /** + * 16 进制转2进制 + * @param inHex + * @return + */ + public static String toTwoHex(String inHex){ + BigInteger sint = new BigInteger(inHex, 16); + //10进制转2进制 + String result = sint.toString(2); + String b= new StringBuilder(result).reverse().toString(); + while (b.length()<8){//低于8位的补0 + b+="0"; + } + return b; + } + + private static byte hexToByte(String inHex) { + return (byte) Integer.parseInt(inHex, 16); + } + + + /** + * 16进制字节数组返回16进制字符 + * + * @param bytes 要被转为16进制字符串的16进制字节流数组 + * @return 返回16进制字符 + */ + public static String bytesToHexString(byte[] bytes) { + char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + // �?个byte�?8位,可用两个十六进制位标�? + char[] buf = new char[bytes.length * 2]; + int a; + int index = 0; + for (byte b : bytes) { // 使用除与取余进行转换 + if (b < 0) { + a = 256 + b; + } else { + a = b; + } + buf[index++] = HEX_CHAR[a / 16]; + buf[index++] = HEX_CHAR[a % 16]; + } + return new String(buf); + } + + // 16进制转普通字符串 + public static String sixTeenHexToString(String hexStr) { + String str = "0123456789ABCDEF"; + char[] hexs = hexStr.toCharArray(); + byte[] bytes = new byte[hexStr.length() / 2]; + int n; + for (int i = 0; i < bytes.length; i++) { + n = str.indexOf(hexs[2 * i]) * 16; + n += str.indexOf(hexs[2 * i + 1]); + bytes[i] = (byte) (n & 0xff); + } + return new String(bytes); + } + + + //数组copy【接收返回的16进制字节流,用于16进制字符串 + + /** + * 数组copy 【接收返回的16进制字节流,用于16进制字符串 + * + * @param src 服务端返回的源数 + * @param begin 起始位置 + * @param count 写入长度 + * @return 返回接收服务端返回数16进制字节流数 + */ + public static byte[] subBytes(byte[] src, int begin, int count) { + byte[] bs = new byte[count]; + System.arraycopy(src, begin, bs, 0, count); + return bs; + } + + /** + * 过滤字符 + * + * @param source + * @param replace + * @return + */ + public static String replaceWrongUnicode(String source, String replace) { + if (StringUtils.isBlank(source)) { + return source; + } + if (StringUtils.isBlank(replace)) { + replace = ""; + } + Pattern CRLF = Pattern.compile("([ ➤▶★■◆■◆♧♡◓◒♠♣♥❤☜☞☎☏⊙◎◚◛◜▧▨♨◐◑↔↕▪ ▒ ◊◦▣▤▥▦▩◘◈◇♬♪♩♭♪の◐◑→あぃ£Ю〒§♤♥▶¤๑⊹⊱⋛⋌⋚⊰⊹≈๑۩۩.. ..۩۩๑๑۩۞۩๑✱❇✾➹ ~.~‿☀☂☁┱┲❣✚✩✣✤✥✦❈❥❦❧❂❁❀✿✄☪☣☢☠☭ღღღ▶▷◀◁☀☁☂☃☄◐◑☇☈⊙☊☋☌☍ⓛⓞⓥⓔ╬『』∴☀ . 。◕‿◕。♨♬♩♭♧◑∷﹌の◐◎▶☺◛►◄▧▨♨◐◑ ↔ ↕↘◜▀▄█▌░▒▬♦◊ ☜☞▐░▒▬♦◊◦ ◜♧の◑→♧ぃ£❤。◕‿◕。✌✟ஐ♧♬๑•ิ.•ิ๑♠♣✖♥►◄↔↕▪▫◘◙の◑→あぃ£❤。◕‿�▲×●]|(…)|(·)|( )|[\\u0000-\\u0019]|[\\u001A-\\u001F]|[\\u001a-\\u001f]|[\\u007f-\\u009f]|\\u00ad|[\\u0483-\\u0489]|[\\u0559-\\u055a]|\\u058a|[\\u0591-\\u05bd]|\\u05bf|[\\u05c1-\\u05c2]|[\\u05c4-\\u05c7]|[\\u0606-\\u060a]|[\\u063b-\\u063f]|\\u0674|[\\u06e5-\\u06e6]|\\u070f|[\\u076e-\\u077f]|\\u0a51|\\u0a75|\\u0b44|[\\u0b62-\\u0b63]|[\\u0c62-\\u0c63]|[\\u0ce2-\\u0ce3]|[\\u0d62-\\u0d63]|\\u135f|[\\u200b-\\u200f]|[\\u2028-\\u202e]|\\u2044|\\u2071|[\\uf701-\\uf70e]|[\\uf710-\\uf71a]|\\ufb1e|[\\ufc5e-\\ufc62]|\\ufeff|\\ufffc)"); + Matcher m = CRLF.matcher(source); + if (m.find()) { + return m.replaceAll(replace); + } + return source; + } + public static float hexToFloat2(String hexString) { + Float f = Float.intBitsToFloat(new BigInteger(hexString, 16).intValue()); + return f; + } + /** + * 16进制 转 float + * @param hexString + * @return + */ + public static float hexToFloat(String hexString) { + int intValue = Integer.parseInt(hexString, 16); + return Float.intBitsToFloat(intValue); + } + + /** + *float -转 16进制 + * @param value + * @return + */ + public static String toFixFloat(Float value){ + String data =Integer.toHexString(Float.floatToIntBits(value)); + return data; + } + +} diff --git a/src/main/java/com/bonus/aqd/tcpservice/SaveDataService.java b/src/main/java/com/bonus/aqd/tcpservice/SaveDataService.java index c92e297..97a766f 100644 --- a/src/main/java/com/bonus/aqd/tcpservice/SaveDataService.java +++ b/src/main/java/com/bonus/aqd/tcpservice/SaveDataService.java @@ -80,6 +80,9 @@ public class SaveDataService { VO.setDevBtime(time); //有告警 if(WsConfig.warn.equals(hanger_a_status) || WsConfig.warn.equals(hanger_b_status)){ + // 查询告警 通道 + String warnChann=mapper.getWarnChann(imei); + sendMessageToClient(warnChann,"55aa78865ccd110202000000000d"); if(WsConfig.warn.equals(hanger_a_status) && WsConfig.warn.equals(hanger_b_status)){ warnInfoVo.setWarnContent("双钩脱落"); warnInfoVo.setWarnReason("双钩-双钩脱落"); @@ -96,10 +99,12 @@ public class SaveDataService { warnInfoVo.setDevModule("单钩"); VO.setWarnInfo("2"); } - // 查询告警 通道 - String warnChann=mapper.getWarnChann(imei); - sendMessageToClient(warnChann,"55aa78865ccd000103000000000d"); + + mapper.insertWarnInfo(warnInfoVo); + }else{ + String warnChann=mapper.getWarnChann(imei); + sendMessageToClient(warnChann,"55aa78865ccd110201000000000d"); } //蓝牙终端 if(WsConfig.err.equals(hanger_a_status) || WsConfig.err.equals(hanger_b_status)){ @@ -138,7 +143,7 @@ public class SaveDataService { if(StringHelper.isNotEmpty(str)){ updateDataStatus2(str,channId); } - System.err.println(str); + // System.err.println(str); }); }catch (Exception e){ log.error(e.toString(),e); @@ -181,6 +186,7 @@ public class SaveDataService { try { Integer decimal = Integer.parseInt(msg.substring(0, 8), 16); String devCode = decimal.toString(); + System.err.println("声光告警设备编码-->"+devCode); DevVO VO = new DevVO(); VO.setDevCode(devCode); VO.setChannId(chinnId); @@ -260,24 +266,27 @@ public class SaveDataService { public static void main(String[] args) { - String msg1="78 86 5C CD 10 01 00 00 00 00 00 0D"; - String msg="78865CCD100100000000000D"; - int decimal = Integer.parseInt(msg.substring(0,8), 16); - String msg11=msg.substring(2,4); - String msg2=msg.substring(8,10); - String msg3=msg.substring(10,12); - String msg4=msg.substring(12,14); - System.err.println(msg11); - System.err.println(msg2); - System.err.println(msg3); - System.err.println(msg4); - int decimal3= Integer.parseInt(msg.substring(8,10), 16); - System.err.println(decimal3); - System.err.println(decimal); + } public String getResult(int i) { String result= aqdMapper.getConfigData(i); return result; } + + /** + * 数据告警 + * @param msg + */ + public void warnInfo(String msg) { + try{ + System.err.println("告警了"); + JSONObject obj=JSONObject.parseObject(msg); + String imei=obj.getString("imei"); + String warnChann=mapper.getWarnChann(imei); + sendMessageToClient(warnChann,"55aa78865ccd110202000000000d"); + }catch (Exception e){ + log.error(e.toString()); + } + } } diff --git a/src/main/java/com/bonus/aqd/websocket/config/WsConfig.java b/src/main/java/com/bonus/aqd/websocket/config/WsConfig.java index 4b6f853..8bf8f00 100644 --- a/src/main/java/com/bonus/aqd/websocket/config/WsConfig.java +++ b/src/main/java/com/bonus/aqd/websocket/config/WsConfig.java @@ -8,6 +8,8 @@ public class WsConfig { public static String login="ca_login"; public static String location="ca_report_location"; + public static String sos="ca_sos"; + public static String warn="0"; diff --git a/src/main/java/com/bonus/aqd/websocket/handle/AqdSocketHandler.java b/src/main/java/com/bonus/aqd/websocket/handle/AqdSocketHandler.java index 371d124..3b6b2ac 100644 --- a/src/main/java/com/bonus/aqd/websocket/handle/AqdSocketHandler.java +++ b/src/main/java/com/bonus/aqd/websocket/handle/AqdSocketHandler.java @@ -51,6 +51,9 @@ public class AqdSocketHandler implements org.springframework.web.socket.WebSocke }else if(WsConfig.login.equals(act)){ String devId=json.getString("device_id"); service.updateStatus(devId,session.getId()); + }else if(WsConfig.warn.equals(act)){ + service.warnInfo(msg); + res.put("msg","数据上传成功!"); } res.put("cmd",act); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f05cf24..184705f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,6 @@ # 配置端口 server: - port: 21994 + port: 21995 # servlet: # context-path: /aqd_screen max-http-header-size: 10240 @@ -39,5 +39,5 @@ zhly: enable: false netty: - port: 21995 + port: 21994