websocket 数据对接

This commit is contained in:
haozq 2024-08-19 16:42:02 +08:00
parent b4c296d3b8
commit 511931e3a5
7 changed files with 392 additions and 27 deletions

View File

@ -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();
}

View File

@ -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("声光告警设备不在线:");
}
}
}

View File

@ -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<Double> getData2(String msg){
List<Double> list=new ArrayList();
try {
if(StringHelper.isNotEmpty(msg)){
String[] msr=msg.split(" ");
for (int i = 0; i <msr.length ; i++) {
if(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<Double> getData3(String msg){
List<Double> list=new ArrayList();
try {
if(StringHelper.isNotEmpty(msg)){
String[] msr=msg.split(" ");
for (int i = 0; i <msr.length ; i++) {
if(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<Double> getData(String msg){
List<Double> list=new ArrayList();
try{
StringBuilder builder=new StringBuilder();
if(StringHelper.isNotEmpty(msg)){
String[] msr=msg.split(" ");
for (int i = 0; i <msr.length ; i++) {
if(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'};
// <EFBFBD>?个byte<EFBFBD>?8位可用两个十六进制位标<EFBFBD>?
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("([&#xa0;➤▶★■◆■◆♧♡◓◒♠♣♥❤☜☞☎☏⊙◎◚◛◜▧▨♨◐◑↔↕▪ ▒ ◊◦▣▤▥▦▩◘◈◇♬♪♩♭♪の◐◑→あぃ£Ю〒§♤♥▶¤๑⊹⊱⋛⋌⋚⊰⊹≈๑۩۩.. ..۩۩๑๑۩۞۩๑✱❇✾➹ ~.~‿☀☂☁┱┲❣✚✩✣✤✥✦❈❥❦❧❂❁❀✿✄☪☣☢☠☭ღღღ▶▷◀◁☀☁☂☃☄◐◑☇☈⊙☊☋☌☍ⓛⓞⓥⓔ╬『』∴☀ . 。◕‿◕。♨♬♩♭♧◑∷﹌の◐◎▶☺◛►◄▧▨♨◐◑ ↔ ↕↘◜▀▄█▌░▒▬♦◊ ☜☞▐░▒▬♦◊◦ ◜♧の◑→♧ぃ£❤。◕‿◕。✌✟ஐ♧♬๑•ิ.•ิ๑♠♣✖♥►◄↔↕▪▫◘◙の◑→あぃ£❤。◕‿<E29795>×●]|(&hellip;)|(&middot;)|(&nbsp;)|[\\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;
}
}

View File

@ -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());
}
}
}

View File

@ -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";

View File

@ -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);

View File

@ -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