26 files added
10 files modified
1 files deleted
| | |
| | | .authorizeHttpRequests((requests) -> { |
| | | permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll()); |
| | | // 对于登录login 注册register 验证码captchaImage 允许匿名访问 |
| | | requests.antMatchers("/login", "/register", "/captchaImage").permitAll() |
| | | requests.antMatchers("/login", "/register", "/captchaImage", "/ws/**").permitAll() |
| | | // 静态资源,可匿名访问 |
| | | .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() |
| | | .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() |
| | |
| | | <artifactId>protobuf-java</artifactId> |
| | | <version>3.20.1</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-websocket</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | <build> |
| | |
| | | private ITyService tyService; |
| | | |
| | | |
| | | |
| | | @ApiOperation(value = "云台转动(基于角度)", notes = "actionCode值:0-回中,1-上,2-右上,3-右,4-右下,5-下,6-左下,7-左,8-左上,254-停止") |
| | | @ApiOperation(value = "云台转动(基于角度)", notes = "actionCode值:0-回中,1-上,2-右上,3-右,4-右下,5-下,6-左下,7-左,8-左上,254-停止 \r\n rotationAngle值:取值范围:0~255【云台实际转动角度= 转动角度/100+2.5 单位:度】") |
| | | @ApiOperationSupport(order = 1) |
| | | @PostMapping("/angleControl") |
| | | public AjaxResult angleControl(@RequestBody AngleControlDTO angleControlDto) { |
| | |
| | | package com.ard.tianyu.controller; |
| | | |
| | | import com.ard.common.core.domain.AjaxResult; |
| | | import com.ard.tianyu.model.dto.manual.ReturnHomeDTO; |
| | | import com.ard.tianyu.model.dto.manual.SwitchUavControlDTO; |
| | | import com.ard.tianyu.model.dto.manual.TakeOffDTO; |
| | | import com.ard.tianyu.model.dto.manual.*; |
| | | import com.ard.tianyu.service.ITyService; |
| | | import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; |
| | | import io.swagger.annotations.Api; |
| | |
| | | tyService.switchUavControl(switchUavControlDTO); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation(value = "起飞", notes = "起飞高度height取值范围:1.2~100,误差:+-0.4米") |
| | | @ApiOperationSupport(order = 2) |
| | | @PostMapping("/takeOff") |
| | |
| | | tyService.returnHome(returnHomeDTO); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation("取消返航") |
| | | @ApiOperationSupport(order = 4) |
| | | @PostMapping("/returnHomeCancel") |
| | | public AjaxResult returnHomeCancel(@RequestBody ReturnHomeCancelDTO returnHomeCancelDTO) { |
| | | tyService.returnHomeCancel(returnHomeCancelDTO); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation("降落") |
| | | @ApiOperationSupport(order = 5) |
| | | @PostMapping("/land") |
| | | public AjaxResult land(@RequestBody LandDTO landDTO) { |
| | | tyService.land(landDTO); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation("取消降落") |
| | | @ApiOperationSupport(order = 6) |
| | | @PostMapping("/landCancel") |
| | | public AjaxResult landCancel(@RequestBody LandCancelDTO landCancelDTO) { |
| | | tyService.landCancel(landCancelDTO); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation("强制降落") |
| | | @ApiOperationSupport(order = 7) |
| | | @PostMapping("/landForced") |
| | | public AjaxResult landForced(@RequestBody LandForcedDTO landForcedDTO) { |
| | | tyService.landForced(landForcedDTO); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation(value = "方向控制", notes = "前后速度frSpeed:【前0至30 后0至-30】单位m/s " + |
| | | "左右速度lrSpeed:【右0至30 左0至-30】单位m/s " + |
| | | "上下速度udSpeed:【上0至5 后0至-5 】单位m/s 偏航角yaw:-150~150 deg/s") |
| | | @ApiOperationSupport(order = 8) |
| | | @PostMapping("/flyControl") |
| | | public AjaxResult flyControl(@RequestBody FlyControlDTO flyControlDTO) { |
| | | tyService.flyControl(flyControlDTO); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation(value = "开始指点飞行", notes = "速度speed:0~20 单位m/s " + |
| | | "飞行模式flyMode:0-节能模式【飞机直线飞到目标点,需飞机在空中】," + |
| | | "1-安全模式【飞机飞行至目标点高度再平飞到目标点,飞机可以在地面或空中】 默认为节能模式") |
| | | @ApiOperationSupport(order = 9) |
| | | @PostMapping("/flyPointControl") |
| | | public AjaxResult flyPointControl(@RequestBody FlyPointControlDTO flyPointControlDTO) { |
| | | tyService.flyPointControl(flyPointControlDTO); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation("停止指点飞行") |
| | | @ApiOperationSupport(order = 10) |
| | | @PostMapping("/flyPointControlCancel") |
| | | public AjaxResult flyPointControlCancel(@RequestBody FlyPointControlCancelDTO flyPointControlCancelDTO) { |
| | | tyService.flyPointControlCancel(flyPointControlCancelDTO); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation(value = "紧急制动", notes = "动作参数actionParam: 0-解除紧急制动 1-紧急制动") |
| | | @ApiOperationSupport(order = 11) |
| | | @PostMapping("/emeragencyBrake") |
| | | public AjaxResult emeragencyBrake(@RequestBody EmeragencyBrakeDTO emeragencyBrakeDTO) { |
| | | tyService.emeragencyBrake(emeragencyBrakeDTO); |
| | | return AjaxResult.success(); |
| | | } |
| | | } |
| | |
| | | * 修改云盒设置 |
| | | */ |
| | | @Post(TyConst.POST_BOX_UPDATE) |
| | | TyHttpCommonReceiver updateBoxSettings(@JSONBody BoxSettingsDTO boxSettingsDTO, @Header Map<String, String> headers); |
| | | TyHttpCommonReceiver<?> updateBoxSettings(@JSONBody BoxSettingsDTO boxSettingsDTO, @Header Map<String, String> headers); |
| | | } |
| | |
| | | * 照片实时回传开关,0-关闭,1-开启 |
| | | */ |
| | | @JsonProperty("openImgRtp") |
| | | private String openImgRtp; |
| | | private Integer openImgRtp; |
| | | |
| | | /** |
| | | * 视频包排序开关,0-关闭,1-开启(排序会增加视频延时) |
| | | */ |
| | | @JsonProperty("openVideoSort") |
| | | private String openVideoSort; |
| | | private Integer openVideoSort; |
| | | |
| | | /** |
| | | * 云端视频存储开关,0-关闭,1-开启 |
| | | */ |
| | | @JsonProperty("openVideoStorage") |
| | | private String openVideoStorage; |
| | | private Integer openVideoStorage; |
| | | |
| | | /** |
| | | * 视频自动推流开关,0-关闭,1-开启 |
| | | */ |
| | | @JsonProperty("videoAutoPush") |
| | | private String videoAutoPush; |
| | | private Integer videoAutoPush; |
| | | |
| | | /** |
| | | * 云盒固件自动升级开关,0-关闭,1-开启 |
| | | */ |
| | | @JsonProperty("autoUpdate") |
| | | private String autoUpdate; |
| | | private Integer autoUpdate; |
| | | |
| | | /** |
| | | * 云盒与平台失联xx秒后自动返航 |
| | | */ |
| | | @JsonProperty("lostTime") |
| | | private String lostTime; |
| | | private Integer lostTime; |
| | | |
| | | /** |
| | | * 低电量自动返航开关:0-关闭,1-智能计算,xx-指定的返航电量 |
| | | */ |
| | | @JsonProperty("minHomeBattery") |
| | | private String minHomeBattery; |
| | | private Integer minHomeBattery; |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.model.dto.manual; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * 紧急制动实体对象 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日9:02 |
| | | **/ |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class EmeragencyBrakeDTO { |
| | | private String boxSn; |
| | | |
| | | //0x00-解除紧急制动 0x01-紧急制动 |
| | | private byte actionParam; |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.model.dto.manual; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * 方向控制实体对象 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日9:02 |
| | | **/ |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class FlyControlDTO { |
| | | |
| | | private String boxSn; |
| | | |
| | | /** |
| | | * 前后速度 |
| | | */ |
| | | private Float frSpeed; |
| | | /** |
| | | * 左右速度 |
| | | */ |
| | | private Float lrSpeed; |
| | | /** |
| | | * 上下速度 |
| | | */ |
| | | private Float udSpeed; |
| | | |
| | | /** |
| | | * 偏航角 |
| | | */ |
| | | private Float yaw; |
| | | |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.model.dto.manual; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * 停止指点飞行实体对象 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日9:02 |
| | | **/ |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class FlyPointControlCancelDTO { |
| | | private String boxSn; |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.model.dto.manual; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * 指点飞行控制实体对象 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日9:02 |
| | | **/ |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class FlyPointControlDTO { |
| | | |
| | | private String boxSn; |
| | | |
| | | /** |
| | | * 经度 |
| | | */ |
| | | private Double longitude; |
| | | /** |
| | | * 纬度 |
| | | */ |
| | | private Double latitude; |
| | | /** |
| | | * 高度 |
| | | */ |
| | | private Float altitude; |
| | | |
| | | /** |
| | | * 速度 |
| | | */ |
| | | private Float speed; |
| | | |
| | | /** |
| | | * 飞行模式 |
| | | */ |
| | | @Builder.Default |
| | | private byte flyMode = 0; |
| | | |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.model.dto.manual; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * 取消降落实体对象 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日9:02 |
| | | **/ |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class LandCancelDTO { |
| | | private String boxSn; |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.model.dto.manual; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * 降落实体对象 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日9:02 |
| | | **/ |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class LandDTO { |
| | | private String boxSn; |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.model.dto.manual; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * 取消降落实体对象 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日9:02 |
| | | **/ |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class LandForcedDTO { |
| | | private String boxSn; |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.model.dto.manual; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | /** |
| | | * 取消返航实体对象 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日9:02 |
| | | **/ |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class ReturnHomeCancelDTO { |
| | | private String boxSn; |
| | | } |
| | |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | @Validated |
| | | public class ReturnHomeDTO { |
| | | private String boxSn; |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.model.dto.manual.EmeragencyBrakeDTO; |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | |
| | | /** |
| | | * 紧急制动指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月30日16:20 |
| | | **/ |
| | | public class EmergencyBrakeCmd extends BaseCmd { |
| | | |
| | | private final byte actionParam; //动作参数 |
| | | |
| | | public EmergencyBrakeCmd(EmeragencyBrakeDTO emeragencyBrakeDTO) { |
| | | setDataHeader((short) 0x7479); |
| | | setDataLength((short) 19); |
| | | setBoxSn(emeragencyBrakeDTO.getBoxSn().getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | this.actionParam = emeragencyBrakeDTO.getActionParam(); |
| | | } |
| | | |
| | | |
| | | public void encode(ByteBuf out) { |
| | | out.writeShort(getDataHeader()); // 写入数据头 |
| | | out.writeShort(getDataLength()); // 写入数据长度 |
| | | out.writeBytes(getBoxSn()); // 写入盒子SN |
| | | out.writeByte(getCmdCode()); // 写入命令码 |
| | | out.writeByte(0x00); // 写入加密标志 |
| | | out.writeByte(0x32); // 写入动作编号 |
| | | out.writeByte(this.actionParam); // 写入动作参数 |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.model.dto.manual.EmeragencyBrakeDTO; |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 紧急制动回复指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月30日16:20 |
| | | **/ |
| | | @Data |
| | | public class EmergencyBrakeReplyCmd extends BaseCmd { |
| | | |
| | | private final byte encryptFlag = 0x00; // 加密标志 |
| | | private final byte actionCode = 0x32; // 动作编号 |
| | | private final byte result; // 执行结果 |
| | | private final Integer errorCode; // 错误码 |
| | | |
| | | public EmergencyBrakeReplyCmd(String boxSn, Byte result, Integer errorCode) { |
| | | setDataHeader((short) 0x6A77); |
| | | setDataLength((short) 23); |
| | | setBoxSn(boxSn.getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | this.result = result; |
| | | this.errorCode = errorCode; |
| | | } |
| | | |
| | | public void encode(ByteBuf out) { |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.model.dto.manual.FlyControlDTO; |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | |
| | | /** |
| | | * 方向控制指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | public class FlyControlCmd extends BaseCmd { |
| | | private final float frSpeed; // 前后速度 |
| | | private final float lrSpeed; // 左右速度 |
| | | private final float udSpeed; // 上下速度 |
| | | private final float yaw; // 偏航角 |
| | | private final short execTime = 200; // 执行时间 |
| | | |
| | | public FlyControlCmd(FlyControlDTO flyControlDTO) { |
| | | setDataHeader((short) 0x7479); |
| | | setDataLength((short) 36); |
| | | setBoxSn(flyControlDTO.getBoxSn().getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | this.frSpeed = flyControlDTO.getFrSpeed(); |
| | | this.lrSpeed = flyControlDTO.getLrSpeed(); |
| | | this.udSpeed = flyControlDTO.getUdSpeed(); |
| | | this.yaw = flyControlDTO.getYaw(); |
| | | } |
| | | |
| | | |
| | | public void encode(ByteBuf out) { |
| | | out.writeShort(getDataHeader()); // 写入数据头 |
| | | out.writeShort(getDataLength()); // 写入数据长度 |
| | | out.writeBytes(getBoxSn()); // 写入盒子SN |
| | | out.writeByte(getCmdCode()); // 写入命令码 |
| | | out.writeByte(0x00); // 写入加密标志 |
| | | out.writeByte(0x28); // 写入动作编号 |
| | | out.writeFloat(frSpeed); // 写入前后速度 |
| | | out.writeFloat(lrSpeed); // 写入左右速度 |
| | | out.writeFloat(udSpeed); // 写入上下速度 |
| | | out.writeFloat(yaw); // 写入偏航角 |
| | | out.writeShort(execTime); // 写入执行时间 |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.model.dto.manual.FlyPointControlCancelDTO; |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | |
| | | /** |
| | | * 停止指点飞行指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | public class FlyPointControlCancelCmd extends BaseCmd { |
| | | |
| | | |
| | | public FlyPointControlCancelCmd(FlyPointControlCancelDTO flyPointControlCancelDTO) { |
| | | setDataHeader((short) 0x7479); |
| | | setDataLength((short) 18); |
| | | setBoxSn(flyPointControlCancelDTO.getBoxSn().getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | } |
| | | |
| | | |
| | | public void encode(ByteBuf out) { |
| | | out.writeShort(getDataHeader()); // 写入数据头 |
| | | out.writeShort(getDataLength()); // 写入数据长度 |
| | | out.writeBytes(getBoxSn()); // 写入盒子SN |
| | | out.writeByte(getCmdCode()); // 写入命令码 |
| | | out.writeByte(0x00); // 写入加密标志 |
| | | out.writeByte(0x3A); // 写入动作编号 |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.model.dto.manual.FlyPointControlDTO; |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | |
| | | /** |
| | | * 指点飞行控制指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | public class FlyPointControlCmd extends BaseCmd { |
| | | private final double longitude; // 经度 |
| | | private final double latitude; // 纬度 |
| | | private final float altitude; // 高度 |
| | | private final float speed; // 速度 |
| | | private final byte flyMode; // 飞行模式 |
| | | |
| | | public FlyPointControlCmd(FlyPointControlDTO flyPointControlDTO) { |
| | | setDataHeader((short) 0x7479); |
| | | setDataLength((short) 36); |
| | | setBoxSn(flyPointControlDTO.getBoxSn().getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | this.longitude = flyPointControlDTO.getLongitude(); |
| | | this.latitude = flyPointControlDTO.getLatitude(); |
| | | this.altitude = flyPointControlDTO.getAltitude(); |
| | | this.speed = flyPointControlDTO.getSpeed(); |
| | | this.flyMode = flyPointControlDTO.getFlyMode(); |
| | | } |
| | | |
| | | |
| | | public void encode(ByteBuf out) { |
| | | out.writeShort(getDataHeader()); // 写入数据头 |
| | | out.writeShort(getDataLength()); // 写入数据长度 |
| | | out.writeBytes(getBoxSn()); // 写入盒子SN |
| | | out.writeByte(getCmdCode()); // 写入命令码 |
| | | out.writeByte(0x00); // 写入加密标志 |
| | | out.writeByte(0x39); // 写入动作编号 |
| | | out.writeDouble(longitude); // 写入经度 |
| | | out.writeDouble(latitude); // 写入纬度 |
| | | out.writeFloat(altitude); // 写入高度 |
| | | out.writeFloat(speed); // 写入速度 |
| | | out.writeByte(flyMode); // 写入飞行模式 |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.model.dto.manual.LandCancelDTO; |
| | | import com.ard.tianyu.model.dto.manual.LandDTO; |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | |
| | | /** |
| | | * 取消降落指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | public class LandCancelCmd extends BaseCmd { |
| | | |
| | | |
| | | public LandCancelCmd(LandCancelDTO landCancleDTO) { |
| | | setDataHeader((short) 0x7479); |
| | | setDataLength((short) 18); |
| | | setBoxSn(landCancleDTO.getBoxSn().getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | } |
| | | |
| | | |
| | | public void encode(ByteBuf out) { |
| | | out.writeShort(getDataHeader()); // 写入数据头 |
| | | out.writeShort(getDataLength()); // 写入数据长度 |
| | | out.writeBytes(getBoxSn()); // 写入盒子SN |
| | | out.writeByte(getCmdCode()); // 写入命令码 |
| | | out.writeByte(0x00); // 写入加密标志 |
| | | out.writeByte(0x15); // 写入动作编号 |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 取消降落回复指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | @Data |
| | | public class LandCancelReplyCmd extends BaseCmd { |
| | | |
| | | private final byte encryptFlag = 0x00; // 加密标志 |
| | | private final byte actionCode = 0x15; // 动作编号 |
| | | private final byte result; // 执行结果 |
| | | private final Integer errorCode; // 错误码 |
| | | |
| | | public LandCancelReplyCmd(String boxSn, Byte result, Integer errorCode) { |
| | | setDataHeader((short) 0x6A77); |
| | | setDataLength((short) 23); |
| | | setBoxSn(boxSn.getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | this.result = result; |
| | | this.errorCode = errorCode; |
| | | } |
| | | |
| | | public void encode(ByteBuf out) { |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.model.dto.manual.LandDTO; |
| | | import com.ard.tianyu.model.dto.manual.ReturnHomeCancelDTO; |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | |
| | | /** |
| | | * 降落指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | public class LandCmd extends BaseCmd { |
| | | |
| | | |
| | | public LandCmd(LandDTO landDTO) { |
| | | setDataHeader((short) 0x7479); |
| | | setDataLength((short) 18); |
| | | setBoxSn(landDTO.getBoxSn().getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | } |
| | | |
| | | |
| | | public void encode(ByteBuf out) { |
| | | out.writeShort(getDataHeader()); // 写入数据头 |
| | | out.writeShort(getDataLength()); // 写入数据长度 |
| | | out.writeBytes(getBoxSn()); // 写入盒子SN |
| | | out.writeByte(getCmdCode()); // 写入命令码 |
| | | out.writeByte(0x00); // 写入加密标志 |
| | | out.writeByte(0x14); // 写入动作编号 |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.model.dto.manual.LandCancelDTO; |
| | | import com.ard.tianyu.model.dto.manual.LandForcedDTO; |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | |
| | | /** |
| | | * 强制降落指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | public class LandForcedCmd extends BaseCmd { |
| | | |
| | | |
| | | public LandForcedCmd(LandForcedDTO landForcedDTO) { |
| | | setDataHeader((short) 0x7479); |
| | | setDataLength((short) 18); |
| | | setBoxSn(landForcedDTO.getBoxSn().getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | } |
| | | |
| | | |
| | | public void encode(ByteBuf out) { |
| | | out.writeShort(getDataHeader()); // 写入数据头 |
| | | out.writeShort(getDataLength()); // 写入数据长度 |
| | | out.writeBytes(getBoxSn()); // 写入盒子SN |
| | | out.writeByte(getCmdCode()); // 写入命令码 |
| | | out.writeByte(0x00); // 写入加密标志 |
| | | out.writeByte(0x29); // 写入动作编号 |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 强制降落回复指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | @Data |
| | | public class LandForcedReplyCmd extends BaseCmd { |
| | | |
| | | private final byte encryptFlag = 0x00; // 加密标志 |
| | | private final byte actionCode = 0x29; // 动作编号 |
| | | private final byte result; // 执行结果 |
| | | private final Integer errorCode; // 错误码 |
| | | |
| | | public LandForcedReplyCmd(String boxSn, Byte result, Integer errorCode) { |
| | | setDataHeader((short) 0x6A77); |
| | | setDataLength((short) 23); |
| | | setBoxSn(boxSn.getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | this.result = result; |
| | | this.errorCode = errorCode; |
| | | } |
| | | |
| | | public void encode(ByteBuf out) { |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 降落回复指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | @Data |
| | | public class LandReplyCmd extends BaseCmd { |
| | | |
| | | private final byte encryptFlag = 0x00; // 加密标志 |
| | | private final byte actionCode = 0x14; // 动作编号 |
| | | private final byte result; // 执行结果 |
| | | private final Integer errorCode; // 错误码 |
| | | |
| | | public LandReplyCmd(String boxSn, Byte result, Integer errorCode) { |
| | | setDataHeader((short) 0x6A77); |
| | | setDataLength((short) 23); |
| | | setBoxSn(boxSn.getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | this.result = result; |
| | | this.errorCode = errorCode; |
| | | } |
| | | |
| | | public void encode(ByteBuf out) { |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 到达指点飞行位置回复指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | @Data |
| | | public class PointControlReachedReplyCmd extends BaseCmd { |
| | | |
| | | private final byte encryptFlag = 0x00; // 加密标志 |
| | | private final byte actionCode = 0x39; // 动作编号 |
| | | private final byte result; // 执行结果 |
| | | private final Integer errorCode; // 错误码 |
| | | |
| | | public PointControlReachedReplyCmd(String boxSn, Byte result, Integer errorCode) { |
| | | setDataHeader((short) 0x6A77); |
| | | setDataLength((short) 19); |
| | | setBoxSn(boxSn.getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | this.result = result; |
| | | this.errorCode = errorCode; |
| | | } |
| | | |
| | | public void encode(ByteBuf out) { |
| | | |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.model.dto.manual.ReturnHomeCancelDTO; |
| | | import com.ard.tianyu.model.dto.manual.ReturnHomeDTO; |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | |
| | | /** |
| | | * 取消返航指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | public class ReturnHomeCancelCmd extends BaseCmd { |
| | | |
| | | |
| | | public ReturnHomeCancelCmd(ReturnHomeCancelDTO returnHomeCancelDTO) { |
| | | setDataHeader((short) 0x7479); |
| | | setDataLength((short) 18); |
| | | setBoxSn(returnHomeCancelDTO.getBoxSn().getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | } |
| | | |
| | | |
| | | public void encode(ByteBuf out) { |
| | | out.writeShort(getDataHeader()); // 写入数据头 |
| | | out.writeShort(getDataLength()); // 写入数据长度 |
| | | out.writeBytes(getBoxSn()); // 写入盒子SN |
| | | out.writeByte(getCmdCode()); // 写入命令码 |
| | | out.writeByte(0x00); // 写入加密标志 |
| | | out.writeByte(0x13); // 写入动作编号 |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.netty.command.manual; |
| | | |
| | | import com.ard.tianyu.netty.command.BaseCmd; |
| | | import io.netty.buffer.ByteBuf; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 取消返航回复指令 |
| | | * |
| | | * @author liusuyi |
| | | * @date 2024年10月26日15:43 |
| | | **/ |
| | | @Data |
| | | public class ReturnHomeCancelReplyCmd extends BaseCmd { |
| | | |
| | | private final byte encryptFlag = 0x00; // 加密标志 |
| | | private final byte actionCode = 0x13; // 动作编号 |
| | | private final byte result; // 执行结果 |
| | | private final Integer errorCode; // 错误码 |
| | | |
| | | public ReturnHomeCancelReplyCmd(String boxSn, Byte result, Integer errorCode) { |
| | | setDataHeader((short) 0x6A77); |
| | | setDataLength((short) 23); |
| | | setBoxSn(boxSn.getBytes()); |
| | | setCmdCode((byte) 0xD1); |
| | | this.result = result; |
| | | this.errorCode = errorCode; |
| | | } |
| | | |
| | | public void encode(ByteBuf out) { |
| | | |
| | | } |
| | | } |
| | |
| | | import com.ard.tianyu.netty.command.camera.CapturePicReplyCmd; |
| | | import com.ard.tianyu.netty.command.camera.RecordStartReplyCmd; |
| | | import com.ard.tianyu.netty.command.camera.RecordStopReplyCmd; |
| | | import com.ard.tianyu.netty.command.manual.ReturnHomeReplyCmd; |
| | | import com.ard.tianyu.netty.command.manual.TakeOffReplyCmd; |
| | | import com.ard.tianyu.netty.command.manual.*; |
| | | import com.ard.tianyu.netty.command.notice.BoxPowerStatusReplyCmd; |
| | | import com.ard.tianyu.netty.command.notice.FlyWayEndReplyCmd; |
| | | import com.ard.tianyu.netty.command.notice.UavReadyReplyCmd; |
| | |
| | | baseCmd = new ReturnHomeReplyCmd(boxSn, result, errorCode); |
| | | log.debug("返航回复: {}", boxSn); |
| | | break; |
| | | case 0x13: |
| | | result = in.readByte(); |
| | | errorCode = in.readInt(); |
| | | uavData = new byte[15]; |
| | | in.readBytes(uavData); |
| | | boxSn = new String(uavData); |
| | | baseCmd = new ReturnHomeCancelReplyCmd(boxSn, result, errorCode); |
| | | log.debug("取消返航回复: {}", boxSn); |
| | | break; |
| | | case 0x14: |
| | | result = in.readByte(); |
| | | errorCode = in.readInt(); |
| | | uavData = new byte[15]; |
| | | in.readBytes(uavData); |
| | | boxSn = new String(uavData); |
| | | baseCmd = new LandReplyCmd(boxSn, result, errorCode); |
| | | log.debug("降落回复: {}", boxSn); |
| | | break; |
| | | case 0x15: |
| | | result = in.readByte(); |
| | | errorCode = in.readInt(); |
| | | uavData = new byte[15]; |
| | | in.readBytes(uavData); |
| | | boxSn = new String(uavData); |
| | | baseCmd = new LandCancelReplyCmd(boxSn, result, errorCode); |
| | | log.debug("取消降落回复: {}", boxSn); |
| | | break; |
| | | case 0x29: |
| | | result = in.readByte(); |
| | | errorCode = in.readInt(); |
| | | uavData = new byte[15]; |
| | | in.readBytes(uavData); |
| | | boxSn = new String(uavData); |
| | | baseCmd = new LandForcedReplyCmd(boxSn, result, errorCode); |
| | | log.debug("强制降落回复: {}", boxSn); |
| | | break; |
| | | case 0x32: |
| | | result = in.readByte(); |
| | | errorCode = in.readInt(); |
| | | uavData = new byte[15]; |
| | | in.readBytes(uavData); |
| | | boxSn = new String(uavData); |
| | | baseCmd = new EmergencyBrakeReplyCmd(boxSn, result, errorCode); |
| | | log.debug("紧急制动回复: {}", boxSn); |
| | | break; |
| | | case 0x39: |
| | | result = in.readByte(); |
| | | errorCode = in.readInt(); |
| | | uavData = new byte[15]; |
| | | in.readBytes(uavData); |
| | | boxSn = new String(uavData); |
| | | baseCmd = new PointControlReachedReplyCmd(boxSn, result, errorCode); |
| | | log.debug("到达指点飞行位置回复: {}", boxSn); |
| | | break; |
| | | case 0x22: |
| | | result = in.readByte(); |
| | | errorCode = in.readInt(); |
| | |
| | | import com.ard.tianyu.model.dto.control.AbsAngleControlDTO; |
| | | import com.ard.tianyu.model.dto.control.AngleControlDTO; |
| | | import com.ard.tianyu.model.dto.control.SpeedControlDTO; |
| | | import com.ard.tianyu.model.dto.manual.ReturnHomeDTO; |
| | | import com.ard.tianyu.model.dto.manual.SwitchUavControlDTO; |
| | | import com.ard.tianyu.model.dto.manual.TakeOffDTO; |
| | | import com.ard.tianyu.model.dto.manual.*; |
| | | import com.ard.tianyu.model.dto.signal.SignalInfo; |
| | | import com.ard.tianyu.model.dto.state.UavState; |
| | | import com.ard.tianyu.model.dto.telemetry.TelemetryData; |
| | |
| | | * 返航 |
| | | */ |
| | | void returnHome(ReturnHomeDTO returnHomeDTO); |
| | | |
| | | /** |
| | | * 取消返航 |
| | | */ |
| | | void returnHomeCancel(ReturnHomeCancelDTO returnHomeCancelDTO); |
| | | |
| | | /** |
| | | * 降落 |
| | | */ |
| | | void land(LandDTO landDTO); |
| | | |
| | | /** |
| | | * 取消降落 |
| | | */ |
| | | void landCancel(LandCancelDTO landCancelDTO); |
| | | |
| | | /** |
| | | * 强制降落 |
| | | */ |
| | | void landForced(LandForcedDTO landForcedDTO); |
| | | |
| | | /** |
| | | * 方向控制 |
| | | */ |
| | | void flyControl(FlyControlDTO flyControlDTO); |
| | | |
| | | /** |
| | | * 指点飞行控制 |
| | | */ |
| | | void flyPointControl(FlyPointControlDTO flyPointControlDTO); |
| | | |
| | | /** |
| | | * 停止指点飞行控制 |
| | | */ |
| | | void flyPointControlCancel(FlyPointControlCancelDTO flyPointControlCancelDTO); |
| | | |
| | | /** |
| | | * 紧急制动 |
| | | */ |
| | | void emeragencyBrake(EmeragencyBrakeDTO emeragencyBrakeDTO); |
| | | |
| | | /** |
| | | * 获取无人机状态 |
| | | */ |
| | |
| | | import com.ard.tianyu.model.dto.converter.UavSignalInfoConverter; |
| | | import com.ard.tianyu.model.dto.converter.UavStateConverter; |
| | | import com.ard.tianyu.model.dto.converter.UavTelemetryDataConverter; |
| | | import com.ard.tianyu.model.dto.manual.ReturnHomeDTO; |
| | | import com.ard.tianyu.model.dto.manual.SwitchUavControlDTO; |
| | | import com.ard.tianyu.model.dto.manual.TakeOffDTO; |
| | | import com.ard.tianyu.model.dto.manual.*; |
| | | import com.ard.tianyu.model.dto.signal.SignalInfo; |
| | | import com.ard.tianyu.model.dto.state.UavState; |
| | | import com.ard.tianyu.model.dto.telemetry.TelemetryData; |
| | |
| | | import com.ard.tianyu.netty.command.register.*; |
| | | import com.ard.tianyu.netty.handler.ErrorCodeEnum; |
| | | import com.ard.tianyu.service.ITyService; |
| | | import com.ard.tianyu.websocket.utils.WebSocketUtil; |
| | | import io.netty.channel.Channel; |
| | | import io.netty.channel.ChannelFuture; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 取消返航 |
| | | */ |
| | | @Override |
| | | public void returnHomeCancel(ReturnHomeCancelDTO returnHomeCancelDTO) { |
| | | ReturnHomeCancelCmd returnHomeCancelCmd = new ReturnHomeCancelCmd(returnHomeCancelDTO); |
| | | this.sendMessage(tyConfiguration.getIpPort(), returnHomeCancelCmd); |
| | | } |
| | | |
| | | /** |
| | | * 降落 |
| | | */ |
| | | @Override |
| | | public void land(LandDTO landDTO) { |
| | | LandCmd landCmd = new LandCmd(landDTO); |
| | | this.sendMessage(tyConfiguration.getIpPort(), landCmd); |
| | | } |
| | | |
| | | /** |
| | | * 取消降落 |
| | | */ |
| | | @Override |
| | | public void landCancel(LandCancelDTO landCancelDTO) { |
| | | LandCancelCmd landCancelCmd = new LandCancelCmd(landCancelDTO); |
| | | this.sendMessage(tyConfiguration.getIpPort(), landCancelCmd); |
| | | } |
| | | |
| | | /** |
| | | * 强制降落 |
| | | */ |
| | | @Override |
| | | public void landForced(LandForcedDTO landForcedDTO) { |
| | | LandForcedCmd landForcedCmd = new LandForcedCmd(landForcedDTO); |
| | | this.sendMessage(tyConfiguration.getIpPort(), landForcedCmd); |
| | | } |
| | | |
| | | /** |
| | | * 方向控制 |
| | | */ |
| | | @Override |
| | | public void flyControl(FlyControlDTO flyControlDTO) { |
| | | FlyControlCmd flyControlCmd = new FlyControlCmd(flyControlDTO); |
| | | this.sendMessage(tyConfiguration.getIpPort(), flyControlCmd); |
| | | } |
| | | |
| | | /** |
| | | * 指点飞行控制 |
| | | */ |
| | | @Override |
| | | public void flyPointControl(FlyPointControlDTO flyPointControlDTO) { |
| | | FlyPointControlCmd flyPointControlCmd = new FlyPointControlCmd(flyPointControlDTO); |
| | | this.sendMessage(tyConfiguration.getIpPort(), flyPointControlCmd); |
| | | } |
| | | |
| | | /** |
| | | * 停止指点飞行控制 |
| | | */ |
| | | @Override |
| | | public void flyPointControlCancel(FlyPointControlCancelDTO flyPointControlCancelDTO) { |
| | | FlyPointControlCancelCmd flyPointControlCancelCmd = new FlyPointControlCancelCmd(flyPointControlCancelDTO); |
| | | this.sendMessage(tyConfiguration.getIpPort(), flyPointControlCancelCmd); |
| | | } |
| | | |
| | | /** |
| | | * 紧急制动 |
| | | */ |
| | | @Override |
| | | public void emeragencyBrake(EmeragencyBrakeDTO emeragencyBrakeDTO) { |
| | | EmergencyBrakeCmd emergencyBrakeCmd=new EmergencyBrakeCmd(emeragencyBrakeDTO); |
| | | this.sendMessage(tyConfiguration.getIpPort(), emergencyBrakeCmd); |
| | | } |
| | | |
| | | /** |
| | | * 获取无人机状态 |
| | | */ |
| | | @Override |
| | |
| | | UavState uavState = UavStateConverter.convertProtoToEntity(uavStateCmd.getUavState()); |
| | | UavStateCache.putUavState(uavState); |
| | | logPrint("无人机状态", uavState.getBoxSn()); |
| | | WebSocketUtil.sendMessageAll(uavState); |
| | | break; |
| | | case (byte) 0xA9: |
| | | // 处理无人机遥测消息 |
| | |
| | | ReturnHomeReplyCmd returnHomeReplyCmd = (ReturnHomeReplyCmd) tyCommand; |
| | | logPrint("无人机返航", returnHomeReplyCmd.getResult(), returnHomeReplyCmd.getErrorCode()); |
| | | } |
| | | //取消返航回复 |
| | | if (tyCommand instanceof ReturnHomeCancelReplyCmd) { |
| | | ReturnHomeCancelReplyCmd returnHomeCancelReplyCmd = (ReturnHomeCancelReplyCmd) tyCommand; |
| | | logPrint("取消无人机返航", returnHomeCancelReplyCmd.getResult(), returnHomeCancelReplyCmd.getErrorCode()); |
| | | } |
| | | //降落回复 |
| | | if (tyCommand instanceof LandReplyCmd) { |
| | | LandReplyCmd landReplyCmd = (LandReplyCmd) tyCommand; |
| | | logPrint("降落", landReplyCmd.getResult(), landReplyCmd.getErrorCode()); |
| | | } |
| | | //取消降落回复 |
| | | if (tyCommand instanceof LandCancelReplyCmd) { |
| | | LandCancelReplyCmd landCancelReplyCmd = (LandCancelReplyCmd) tyCommand; |
| | | logPrint("取消降落", landCancelReplyCmd.getResult(), landCancelReplyCmd.getErrorCode()); |
| | | } |
| | | //强制降落回复 |
| | | if (tyCommand instanceof LandForcedReplyCmd) { |
| | | LandForcedReplyCmd landForcedReplyCmd = (LandForcedReplyCmd) tyCommand; |
| | | logPrint("强制降落", landForcedReplyCmd.getResult(), landForcedReplyCmd.getErrorCode()); |
| | | } |
| | | //到达指点飞行位置回复 |
| | | if (tyCommand instanceof PointControlReachedReplyCmd) { |
| | | PointControlReachedReplyCmd pointControlReachedReplyCmd = (PointControlReachedReplyCmd) tyCommand; |
| | | logPrint("到达指点飞行位置", pointControlReachedReplyCmd.getResult(), pointControlReachedReplyCmd.getErrorCode()); |
| | | } |
| | | //紧急制动回复 |
| | | if (tyCommand instanceof EmergencyBrakeReplyCmd) { |
| | | EmergencyBrakeReplyCmd emergencyBrakeReplyCmd = (EmergencyBrakeReplyCmd) tyCommand; |
| | | logPrint("紧急制动回复", emergencyBrakeReplyCmd.getResult(), emergencyBrakeReplyCmd.getErrorCode()); |
| | | } |
| | | break; |
| | | default: |
| | | // 处理其他消息 |
| | |
| | | private void logPrint(String message, Object obj) { |
| | | log.debug("收到{}回复{}", message, obj); |
| | | } |
| | | |
| | | //公共日志打印 |
| | | private void logPrint(String message, byte result, Integer errorCode) { |
| | | log.info("收到{}回复:{} 错误码:{}【{}】", |
| New file |
| | |
| | | package com.ard.tianyu.websocket.config; |
| | | |
| | | import com.ard.tianyu.websocket.handler.TyMessageHandler; |
| | | import com.ard.tianyu.websocket.interceptor.TyHandshakeInterceptor; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.web.socket.config.annotation.EnableWebSocket; |
| | | import org.springframework.web.socket.config.annotation.WebSocketConfigurer; |
| | | import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; |
| | | import javax.annotation.Resource; |
| | | |
| | | @Configuration |
| | | @EnableWebSocket |
| | | public class WebSocketConfig implements WebSocketConfigurer { |
| | | |
| | | @Resource |
| | | private TyMessageHandler tyMessageHandler; |
| | | |
| | | @Override |
| | | public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { |
| | | //添加myWebSocketHandler消息处理对象以及websocket连接地址 |
| | | registry.addHandler(tyMessageHandler, "/ws/**") |
| | | //设置允许跨域访问 |
| | | .setAllowedOrigins("*") |
| | | //添加拦截器可实现用户链接前进行权限校验等操作 |
| | | .addInterceptors(new TyHandshakeInterceptor()); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.websocket.handler; |
| | | |
| | | import com.ard.tianyu.websocket.utils.WebSocketUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.socket.CloseStatus; |
| | | import org.springframework.web.socket.TextMessage; |
| | | import org.springframework.web.socket.WebSocketSession; |
| | | import org.springframework.web.socket.handler.TextWebSocketHandler; |
| | | |
| | | @Component |
| | | @Slf4j |
| | | public class TyMessageHandler extends TextWebSocketHandler { |
| | | |
| | | @Override |
| | | public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { |
| | | // 处理接收到的消息 |
| | | String payload = message.getPayload(); |
| | | log.info("【websocket】Received message: " + payload); |
| | | log.info("【websocket】size: " + WebSocketUtil.ONLINE_USER_SESSIONS.size()); |
| | | } |
| | | |
| | | @Override |
| | | public void afterConnectionEstablished(WebSocketSession session) { |
| | | log.info("【websocket】Connected: " + session.getId()); |
| | | String userId = (String) session.getAttributes().get("userId"); |
| | | WebSocketUtil.ONLINE_USER_SESSIONS.put(userId, session); |
| | | log.info("【websocket】size: " + WebSocketUtil.ONLINE_USER_SESSIONS.size()); |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { |
| | | log.info("【websocket】Disconnected: " + session.getId()); |
| | | String userId = (String) session.getAttributes().get("userId"); |
| | | WebSocketUtil.ONLINE_USER_SESSIONS.remove(userId); |
| | | log.info("【websocket】size: " + WebSocketUtil.ONLINE_USER_SESSIONS.size()); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.websocket.interceptor; |
| | | |
| | | import org.springframework.http.server.ServerHttpRequest; |
| | | import org.springframework.http.server.ServerHttpResponse; |
| | | import org.springframework.web.socket.WebSocketHandler; |
| | | import org.springframework.web.socket.server.HandshakeInterceptor; |
| | | |
| | | import java.util.Map; |
| | | |
| | | public class TyHandshakeInterceptor implements HandshakeInterceptor { |
| | | |
| | | @Override |
| | | public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, |
| | | WebSocketHandler wsHandler, Map<String, Object> attributes){ |
| | | //从路径中获取userId |
| | | String path = request.getURI().getPath(); |
| | | String[] segments = path.split("/"); |
| | | if (segments.length > 2) { |
| | | String userId = segments[segments.length - 1]; |
| | | attributes.put("userId", userId); |
| | | } |
| | | //从header中获取userId |
| | | // String userId = request.getHeaders().getFirst("userId"); |
| | | // if (userId != null) |
| | | // { |
| | | // attributes.put("userId", userId); |
| | | // } |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, |
| | | WebSocketHandler wsHandler, Exception ex) { |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ard.tianyu.websocket.utils; |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.socket.TextMessage; |
| | | import org.springframework.web.socket.WebSocketSession; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.InetSocketAddress; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ConcurrentMap; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * @ClassName WebSocketUtils |
| | | * @Description: websocket工具类 |
| | | * @Author 刘苏义 |
| | | * @Date 2023/1/27 7:46 |
| | | * @Version 1.0 |
| | | */ |
| | | @Slf4j |
| | | public final class WebSocketUtil { |
| | | |
| | | // 存储 websocket session |
| | | public static final ConcurrentMap<String, WebSocketSession> ONLINE_USER_SESSIONS = new ConcurrentHashMap<>(); |
| | | |
| | | /** |
| | | * @param session 用户 session |
| | | * @param message 发送内容 |
| | | */ |
| | | public static void sendMessage(WebSocketSession session, String message) { |
| | | if (session == null) { |
| | | return; |
| | | } |
| | | final InetSocketAddress remoteAddress = session.getRemoteAddress(); |
| | | if (remoteAddress == null) { |
| | | return; |
| | | } |
| | | synchronized (session) { |
| | | try { |
| | | log.debug("发送消息:" + message); |
| | | session.sendMessage(new TextMessage(String.join(", ", message))); |
| | | } catch (IOException e) { |
| | | log.error("sendMessage IOException ", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @param session 用户 session |
| | | * @param message 发送内容 |
| | | */ |
| | | public static void sendMessage(WebSocketSession session, Map message) { |
| | | if (session == null) { |
| | | return; |
| | | } |
| | | final InetSocketAddress remoteAddress = session.getRemoteAddress(); |
| | | if (remoteAddress == null) { |
| | | return; |
| | | } |
| | | synchronized (session) { |
| | | try { |
| | | session.sendMessage(new TextMessage(JSONObject.toJSONString(message))); |
| | | } catch (IOException e) { |
| | | log.error("sendMessage IOException ", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static void sendMessage(WebSocketSession session, List message) { |
| | | if (session == null) { |
| | | return; |
| | | } |
| | | final InetSocketAddress remoteAddress = session.getRemoteAddress(); |
| | | if (remoteAddress == null) { |
| | | return; |
| | | } |
| | | synchronized (session) { |
| | | try { |
| | | session.sendMessage(new TextMessage(JSONObject.toJSONString(message))); |
| | | } catch (IOException e) { |
| | | log.error("sendMessage IOException ", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 推送消息到其他客户端 |
| | | * |
| | | * @param message |
| | | */ |
| | | public static void sendMessageAll(String message) { |
| | | ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, message)); |
| | | } |
| | | |
| | | /** |
| | | * 推送消息到其他客户端 |
| | | * |
| | | * @param message |
| | | */ |
| | | public static void sendMessageAll(Map message) { |
| | | JSONObject jsonObject = new JSONObject(message); |
| | | ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, jsonObject.toString())); |
| | | } |
| | | /** |
| | | * 推送消息到其他客户端 |
| | | * |
| | | * @param message |
| | | */ |
| | | public static void sendMessageAll(Object message) { |
| | | String jsonMessage = JSONObject.toJSONString(message); // 确保对象转换为 JSON 字符串 |
| | | ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, jsonMessage)); |
| | | } |
| | | /** |
| | | * 推送消息到其他客户端 |
| | | * |
| | | * @param message |
| | | */ |
| | | public static void sendMessageAll(List message) { |
| | | ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, JSON.toJSONString(message))); |
| | | } |
| | | /** |
| | | * @Author 刘苏义 |
| | | * @Description 发送消息给userId_前缀的人 |
| | | * @Date 2024/7/16 10:24 |
| | | * @Param |
| | | * @return |
| | | */ |
| | | public static void sendMessagePrefix(String targetId, String message) { |
| | | String regex = "^" + Pattern.quote(targetId) + "_\\d+$"; |
| | | Pattern pattern = Pattern.compile(regex); |
| | | ONLINE_USER_SESSIONS.entrySet().stream().filter(entry -> { |
| | | Matcher matcher = pattern.matcher(entry.getKey()); |
| | | return matcher.matches(); |
| | | }).map(Map.Entry::getValue).forEach(session -> WebSocketUtil.sendMessage(session, message)); |
| | | } |
| | | } |