Commit 2b7277a0 by xmh

通了

1 parent f0b6b57f
...@@ -25,17 +25,6 @@ ...@@ -25,17 +25,6 @@
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.viontech.keliu</groupId>
<artifactId>keliu-util</artifactId>
<version>6.0.7-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>maven-scm-provider-integrity</artifactId>
<groupId>org.apache.maven.scm</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
<artifactId>netty-all</artifactId> <artifactId>netty-all</artifactId>
<version>4.1.32.Final</version> <version>4.1.32.Final</version>
...@@ -60,6 +49,16 @@ ...@@ -60,6 +49,16 @@
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
<version>2.5.0</version> <version>2.5.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
...@@ -7,6 +7,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; ...@@ -7,6 +7,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(exclude = org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class) @SpringBootApplication(exclude = org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class)
@Slf4j @Slf4j
public class Application { public class Application {
private final static long REAL_TIME = 0x00000001L;
private final static long NOT_REAL_TIME = 0x00000002L;
public static void main(String[] args) { public static void main(String[] args) {
try { try {
...@@ -15,4 +17,5 @@ public class Application { ...@@ -15,4 +17,5 @@ public class Application {
log.error("error", e); log.error("error", e);
} }
} }
} }
package com.viontech.controller; package com.viontech.controller;
import com.viontech.model.BaseModel;
import com.viontech.netty.ChannelGroup;
import com.viontech.process.Process; import com.viontech.process.Process;
import org.springframework.beans.factory.annotation.Autowired; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.sound.sampled.Line;
/** /**
* . * .
* *
...@@ -13,16 +17,18 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -13,16 +17,18 @@ import org.springframework.web.bind.annotation.RestController;
* @date 2020/8/18 * @date 2020/8/18
*/ */
@RestController @RestController
@Slf4j
public class DataController { public class DataController {
@Autowired
Process process;
@PostMapping("/data") @PostMapping("/data")
public Object receiveData(@RequestBody String dataStr) throws Exception{ public Object receiveData(@RequestBody String dataStr) throws Exception {
process.process(dataStr); log.info("收到一条繁星发来的消息");
BaseModel data = Process.process(dataStr);
return null; if (data != null) {
data.encodeData();
ChannelGroup.broadcast(data);
}
return "success";
} }
......
...@@ -15,10 +15,10 @@ import lombok.experimental.Accessors; ...@@ -15,10 +15,10 @@ import lombok.experimental.Accessors;
@Setter @Setter
@Accessors(chain = true) @Accessors(chain = true)
public class BaseModel { public class BaseModel {
protected Long deviceId; protected long deviceId;
protected Long length; protected long length;
protected Long firstInt; protected long protocol;
protected Long secondInt; protected long flag;
protected byte[] data; protected byte[] data;
...@@ -51,8 +51,8 @@ public class BaseModel { ...@@ -51,8 +51,8 @@ public class BaseModel {
model.setDeviceId(deviceId); model.setDeviceId(deviceId);
model.setLength(length); model.setLength(length);
model.setFirstInt(firstInt); model.setProtocol(firstInt);
model.setSecondInt(secondInt); model.setFlag(secondInt);
if (length > 16) { if (length > 16) {
model.data = new byte[(int) (length - 16)]; model.data = new byte[(int) (length - 16)];
byteBuf.readBytes(model.data); byteBuf.readBytes(model.data);
...@@ -61,8 +61,17 @@ public class BaseModel { ...@@ -61,8 +61,17 @@ public class BaseModel {
return model; return model;
} }
public static int castLong2Int(long data) { public static int toInt(long data) {
return (int) (data & 0xFF); return (int) data;
}
public static byte[] toBytes(int n) {
byte[] b = new byte[4];
b[3] = (byte) (n & 0xff);
b[2] = (byte) (n >> 8 & 0xff);
b[1] = (byte) (n >> 16 & 0xff);
b[0] = (byte) (n >> 24 & 0xff);
return b;
} }
/** /**
...@@ -73,18 +82,24 @@ public class BaseModel { ...@@ -73,18 +82,24 @@ public class BaseModel {
public void to(ByteBuf byteBuf) { public void to(ByteBuf byteBuf) {
encodeData(); encodeData();
byteBuf.writeInt(castLong2Int(deviceId)); byteBuf.writeInt(toInt(deviceId));
byteBuf.writeInt(castLong2Int(length)); byteBuf.writeInt(toInt(length));
byteBuf.writeInt(castLong2Int(firstInt)); byteBuf.writeInt(toInt(protocol));
byteBuf.writeInt(castLong2Int(secondInt)); byteBuf.writeInt(toInt(flag));
if (data != null && data.length > 0) { if (data != null && data.length > 0) {
byteBuf.writeBytes(data); byteBuf.writeBytes(data);
} }
} }
protected void encodeData() { /**
* 重写此方法,将相关的字段组装成 byte[] 并赋值给 data
*/
public void encodeData() {
} }
protected void decodeData() { /**
* 重写此方法,将 byte[] 解析到子类的字段中
*/
public void decodeData() {
} }
} }
package com.viontech.model;
import com.fasterxml.jackson.core.util.ByteArrayBuilder;
import lombok.Getter;
import lombok.Setter;
/**
* .
*
* @author 谢明辉
* @date 2020/8/24
*/
@Getter
@Setter
public class BehaviorModel extends BaseModel {
private final byte[] licensePlateText = new byte[16];
private final byte[] recordingPath = new byte[128];
private final byte[] eventLocation = new byte[32];
private final byte[] eventSnapshotPath = new byte[128];
private int serialNum;
private int recordingStartSecond;
private int recordingStartMillisecond;
private int recordingEndSecond;
private int recordingEndMillisecond;
private int eventStartSecond;
private int eventStartMillisecond;
private int eventEndSecond;
private int eventEndMillisecond;
private int eventCode;
private int laneNo;
private int pictureSize;
private int pictureWidth;
private int pictureHeight;
private int x;
private int y;
private int vehicleType;
private int color1;
private int speed;
private int direction;
private int color2;
private int color3;
private int color1Weights;
private int color2Weights;
private int color3Weights;
private int vehicleCategory;
private int reservedField;
private int recordingDuration;
private int faceWidth;
private int faceHeight;
private byte[] reservedField2 = new byte[24];
private byte[] picture;
@Override
public void encodeData() {
this.length = 16L + 448L + picture.length;
this.protocol = 0x00040006L;
ByteArrayBuilder builder = new ByteArrayBuilder(Math.toIntExact(this.length - 16));
builder.appendFourBytes(serialNum);
builder.appendFourBytes(recordingStartSecond);
builder.appendFourBytes(recordingStartMillisecond);
builder.appendFourBytes(recordingEndSecond);
builder.appendFourBytes(recordingEndMillisecond);
builder.appendFourBytes(eventStartSecond);
builder.appendFourBytes(eventStartMillisecond);
builder.appendFourBytes(eventEndSecond);
builder.appendFourBytes(eventEndMillisecond);
builder.appendFourBytes(laneNo);
builder.appendFourBytes(pictureSize);
builder.appendFourBytes(pictureWidth);
builder.appendFourBytes(pictureHeight);
builder.appendFourBytes(x);
builder.appendFourBytes(y);
builder.write(licensePlateText);
builder.write(recordingPath);
builder.appendFourBytes(vehicleType);
builder.appendFourBytes(color1);
builder.appendFourBytes(speed);
builder.appendFourBytes(direction);
builder.write(eventLocation);
builder.write(eventSnapshotPath);
builder.appendFourBytes(color2);
builder.appendFourBytes(color3);
builder.appendFourBytes(color1Weights);
builder.appendFourBytes(color2Weights);
builder.appendFourBytes(color3Weights);
builder.appendFourBytes(vehicleCategory);
builder.appendFourBytes(reservedField);
builder.appendFourBytes(recordingDuration);
builder.appendFourBytes(faceWidth);
builder.appendFourBytes(faceHeight);
builder.write(reservedField2);
builder.write(picture);
// todo 待crc校验
this.data = builder.resetAndGetFirstSegment();
}
}
package com.viontech.model;
import com.fasterxml.jackson.core.util.ByteArrayBuilder;
import lombok.Getter;
import lombok.Setter;
/**
* .
*
* @author 谢明辉
* @date 2020/8/24
*/
@Getter
@Setter
public class FlowModel extends BaseModel {
private final int[] laneNoAndType = new int[16];
private final int[] traffic = new int[16];
private final int[] avgSpeed = new int[16];
private final int[] maxQueueLen = new int[16];
private final int[] avgDistanceBetweenVehicle = new int[16];
private final int[] trafficSupplement = new int[16];
private int serialNum;
private int time;
private int timeDuring;
private byte[] reservedField = new byte[64];
@Override
public void encodeData() {
this.length = 540L;
this.protocol = 0x00040005L;
ByteArrayBuilder builder = new ByteArrayBuilder(Math.toIntExact(this.length - 16));
builder.appendFourBytes(toInt(deviceId));
builder.appendFourBytes(toInt(length));
builder.appendFourBytes(toInt(protocol));
builder.appendFourBytes(toInt(flag));
builder.appendFourBytes(serialNum);
builder.appendFourBytes(time);
builder.appendFourBytes(timeDuring);
for (int value : laneNoAndType) {
builder.appendFourBytes(value);
}
for (int value : traffic) {
builder.appendFourBytes(value);
}
for (int value : avgSpeed) {
builder.appendFourBytes(value);
}
for (int value : maxQueueLen) {
builder.appendFourBytes(value);
}
for (int value : avgDistanceBetweenVehicle) {
builder.appendFourBytes(value);
}
for (int value : trafficSupplement) {
builder.appendFourBytes(value);
}
builder.write(reservedField);
this.data = builder.resetAndGetFirstSegment();
}
}
...@@ -11,12 +11,12 @@ public class KeepAlive extends BaseModel{ ...@@ -11,12 +11,12 @@ public class KeepAlive extends BaseModel{
@Override @Override
protected void encodeData() { public void encodeData() {
} }
@Override @Override
protected void decodeData() { public void decodeData() {
} }
} }
package com.viontech.model;
/**
* .
*
* @author 谢明辉
* @date 2020/8/21
*/
public class LicensePlateRecord extends BaseModel {
/** 序列号 */
private Long serialNum;
/** 识别车牌时间(秒) */
private Long discernSecondTime;
/** 识别车牌时间(毫秒) */
private Long discernMillisecondTime;
/** 车牌文字 */
private String LicensePlateText;
/** 车牌类型 */
private Long LicensePlateType;
/** 识别可靠度 */
private Long confidence;
/** 车道 */
private Long lane;
/** 车辆类型 */
private Long vehicleType;
/** 图片大小宽高 */
private Long secondPictureSize;
private Long secondPictureWidth;
private Long secondPictureHeight;
private Long firstPictureSize;
private Long firstPictureWidth;
private Long firstPictureHeight;
/** 车牌在第一张图片两种 左上右下 位置 */
private Long patternLeft;
private Long patternTop;
private Long patternRight;
private Long patternBottom;
@Override
protected void encodeData() {
this.firstInt = 0x00020004L;
}
}
...@@ -19,13 +19,13 @@ public class LoginData extends BaseModel { ...@@ -19,13 +19,13 @@ public class LoginData extends BaseModel {
private String password; private String password;
@Override @Override
protected void decodeData() { public void decodeData() {
this.username = new String(data, 0, 32, StandardCharsets.UTF_8); this.username = new String(data, 0, 32, StandardCharsets.UTF_8).trim();
this.password = new String(data, 32, 32, StandardCharsets.UTF_8); this.password = new String(data, 32, 32, StandardCharsets.UTF_8).trim();
} }
@Override @Override
protected void encodeData() { public void encodeData() {
} }
} }
package com.viontech.model;
import com.fasterxml.jackson.core.util.ByteArrayBuilder;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.util.zip.CRC32;
/**
* 发送车牌记录,包含电警记录
*
* @author 谢明辉
* @date 2020/8/21
*/
@Getter
@Setter
@Accessors(chain = true)
public class TrafficModel extends BaseModel {
/** 车牌文字 */
private final byte[] plateText = new byte[16];
/** 经过地点 */
private final byte[] routeLocation = new byte[32];
/** 录像路径 */
private final byte[] videoPath = new byte[128];
/** 第一张照片路径 */
private final byte[] picturePath = new byte[128];
/** 序列号 */
private int serialNum;
/** 识别车牌时间(秒) */
private int discernTime;
/** 识别车牌时间(毫秒) */
private int discernMillisecondTime;
/** 车牌类型 */
private int plateType;
/** 车牌识别可靠度 */
private int confidence;
/** 车道 */
private int lane;
/** 车辆类型 */
private int vehicleType;
/** 图片大小宽高 */
private int secondPictureSize;
private int secondPictureWidth;
private int secondPictureHeight;
private int firstPictureSize;
private int firstPictureWidth;
private int firstPictureHeight;
/** 车牌在第一张图片两种 左上右下 位置 */
private int patternLeft;
private int patternTop;
private int patternRight;
private int patternBottom;
/** 车身颜色 */
private int color;
/** 车速 */
private int speed;
/** 方向 */
private int direction;
/** 厂商标志 */
private int manufacturerLogo;
/** 三个预留位 */
private int reservedField;
private int reservedField2;
private int reservedField3;
/** 车型细分 */
private int vehicleCategory;
/** 车牌结构 1单行2双行3其他 */
private int plateStructure;
/** 违章类型 */
private int illegalType;
/** 预留位 */
private int reservedField4;
/** 第二张图片抓拍时间 */
private int secondPictureTime;
private int secondPictureMillisecondTime;
/** 红灯开始时间 */
private int redLightBeginTime;
private int redLightBeginMillisecondTime;
/** 红灯结束时间 */
private int redLightEndTime;
private int redLightEndMillisecondTime;
/** 限速值 */
private int speedLimit;
/** 超速抓拍值 */
private int overSpeedThreshold;
/** 预留字段 */
private byte[] reservedField5 = new byte[4];
/** picture1 */
private byte[] picture1 = new byte[0];
/** picture2 */
private byte[] picture2 = new byte[0];
@Override
public void encodeData() {
this.protocol = 0x00020004L;
this.length = 16L + 452L + picture1.length + picture2.length + 4;
ByteArrayBuilder builder = new ByteArrayBuilder(Math.toIntExact(this.length - 16 - 4));
builder.appendFourBytes(serialNum);
builder.appendFourBytes(discernTime);
builder.appendFourBytes(discernMillisecondTime);
builder.write(plateText);
builder.appendFourBytes(plateType);
builder.appendFourBytes(confidence);
builder.appendFourBytes(lane);
builder.appendFourBytes(vehicleType);
builder.appendFourBytes(secondPictureSize);
builder.appendFourBytes(secondPictureWidth);
builder.appendFourBytes(secondPictureHeight);
builder.appendFourBytes(firstPictureSize);
builder.appendFourBytes(firstPictureWidth);
builder.appendFourBytes(firstPictureHeight);
builder.appendFourBytes(patternLeft);
builder.appendFourBytes(patternTop);
builder.appendFourBytes(patternRight);
builder.appendFourBytes(patternBottom);
builder.appendFourBytes(color);
builder.appendFourBytes(speed);
builder.appendFourBytes(direction);
builder.appendFourBytes(manufacturerLogo);
builder.write(routeLocation);
builder.write(videoPath);
builder.write(picturePath);
builder.appendFourBytes(reservedField);
builder.appendFourBytes(reservedField2);
builder.appendFourBytes(reservedField3);
builder.appendFourBytes(vehicleCategory);
builder.appendFourBytes(plateStructure);
builder.appendFourBytes(illegalType);
builder.appendFourBytes(reservedField4);
builder.appendFourBytes(secondPictureTime);
builder.appendFourBytes(secondPictureMillisecondTime);
builder.appendFourBytes(redLightBeginTime);
builder.appendFourBytes(redLightBeginMillisecondTime);
builder.appendFourBytes(redLightEndTime);
builder.appendFourBytes(redLightEndMillisecondTime);
builder.appendFourBytes(speedLimit);
builder.appendFourBytes(overSpeedThreshold);
builder.write(reservedField5);
builder.write(picture1);
builder.write(picture2);
byte[] bytes = builder.resetAndGetFirstSegment();
int count = bytes.length;
// crc32
CRC32 crc32 = new CRC32();
crc32.update(bytes);
int value = (int) crc32.getValue();
for (int i = 0; i < count; i++) {
bytes[i] = (byte) (bytes[i] ^ 0x94);
}
this.data = new byte[count + 4];
System.arraycopy(bytes, 0, data, 0, count);
this.data[count++] = (byte) (value >> 24);
this.data[count++] = (byte) (value >> 16);
this.data[count++] = (byte) (value >> 8);
this.data[count] = (byte) value;
}
}
package com.viontech.netty; package com.viontech.netty;
import com.viontech.model.BaseModel;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -56,7 +57,7 @@ public class ChannelGroup { ...@@ -56,7 +57,7 @@ public class ChannelGroup {
* *
* @param msg 消息 * @param msg 消息
*/ */
public static void broadcast(Object msg) { public static void broadcast(BaseModel msg) {
for (Channel channel : DEVICE_CHANNEL_MAP.values()) { for (Channel channel : DEVICE_CHANNEL_MAP.values()) {
try { try {
channel.writeAndFlush(msg).await(); channel.writeAndFlush(msg).await();
......
...@@ -29,15 +29,19 @@ public class NettyReceiverHandler extends ChannelInboundHandlerAdapter { ...@@ -29,15 +29,19 @@ public class NettyReceiverHandler extends ChannelInboundHandlerAdapter {
//注册命令 //注册命令
if (message instanceof LoginData) { if (message instanceof LoginData) {
BaseModel result = new BaseModel().setDeviceId(0L).setLength(16L).setFirstInt(0x00020100L); BaseModel result = new BaseModel().setDeviceId(0L).setLength(16L).setProtocol(0x00020100L);
LoginData logindata = (LoginData) message; LoginData logindata = (LoginData) message;
Long deviceId = logindata.getDeviceId(); Long deviceId = logindata.getDeviceId();
System.out.println(logindata.getUsername());
System.out.println(logindata.getPassword());
if ("admin".equals(logindata.getUsername()) && "admin".equals(logindata.getPassword())) { if ("admin".equals(logindata.getUsername()) && "admin".equals(logindata.getPassword())) {
ChannelGroup.registered(deviceId, ctx.channel()); ChannelGroup.registered(deviceId, ctx.channel());
result.setSecondInt(0L); result.setFlag(0L);
} else { } else {
result.setSecondInt(1L); result.setFlag(1L);
} }
ctx.writeAndFlush(result).await(); ctx.writeAndFlush(result).await();
} else if (message instanceof KeepAlive) { } else if (message instanceof KeepAlive) {
...@@ -51,6 +55,7 @@ public class NettyReceiverHandler extends ChannelInboundHandlerAdapter { ...@@ -51,6 +55,7 @@ public class NettyReceiverHandler extends ChannelInboundHandlerAdapter {
@Override @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause); super.exceptionCaught(ctx, cause);
cause.printStackTrace();
} }
@Override @Override
......
...@@ -41,7 +41,7 @@ public class NettyServer implements CommandLineRunner { ...@@ -41,7 +41,7 @@ public class NettyServer implements CommandLineRunner {
@Override @Override
protected void initChannel(SocketChannel ch) { protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO)); ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024 * 1024 * 1000, 4, 4, -16, 0)); ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024 * 1024 * 1000, 4, 4, -8, 0));
ch.pipeline().addLast(new ByteToMessageCodecHandler()); ch.pipeline().addLast(new ByteToMessageCodecHandler());
ch.pipeline().addLast(new NettyReceiverHandler()); ch.pipeline().addLast(new NettyReceiverHandler());
} }
......
package com.viontech.process; package com.viontech.process;
import com.fasterxml.jackson.databind.ObjectMapper; import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf; import com.viontech.model.BaseModel;
import io.netty.buffer.ByteBufAllocator; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
/** /**
* . * .
...@@ -12,23 +11,31 @@ import java.util.Map; ...@@ -12,23 +11,31 @@ import java.util.Map;
* @author 谢明辉 * @author 谢明辉
* @date 2020/8/20 * @date 2020/8/20
*/ */
public interface Process {
Logger log = LoggerFactory.getLogger(Process.class);
public abstract class Process { /**
* 分类处理繁星发来的数据
public void process(String jsonStr) throws Exception{ *
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.ioBuffer(); * @param jsonStr 繁星发来的数据
ObjectMapper objectMapper=new ObjectMapper(); *
Map jsonMap=objectMapper.readValue(jsonStr,Map.class); * @return 转换成对接方需要的
String vchan_refid= (String) jsonMap.get("vchan_refid"); */
//封装包头,暂未赋值 static BaseModel process(String jsonStr) throws Exception {
byteBuf.writeInt(0); //相机编号为String,他们要的是int,暂时保留 JSONObject jsonObject = JSONObject.parseObject(jsonStr);
byteBuf.writeInt(0); String eventCate = jsonObject.getString("event_cate");
byteBuf.writeInt(0); if (eventCate == null) {
byteBuf.writeInt(0); return null;
}
//封装包体 switch (eventCate) {
getData(jsonMap,byteBuf); case "traffic":
return new TrafficProcess().process(jsonObject);
case "behavior":
return new BehaviorProcess().process(jsonObject);
default:
return null;
}
} }
public abstract void getData(Map jsonMap,ByteBuf byteBuf) throws Exception;
BaseModel process(JSONObject jsonObject) throws Exception;
} }
1=1 1=1
2=2 2=2
3=3 3=3
4=4 4=4
\ No newline at end of file \ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!