diff --git a/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java new file mode 100644 index 0000000..0732347 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java @@ -0,0 +1,59 @@ +package com.casic.missiles.netty; + +import org.springframework.stereotype.Component; + +@Component +public class InstructCode { + + /** + * 设备初始化时需要依次发送1~16号指令 + */ + public static String[] InitCodeArr = { + "1", "设置高压", "set set_voltage 4 1.2\\n", + "2", "复位adc", "cmd set_adc_delay_rst 1 0\\n", + "3", "逻辑复位", "cmd set_logic_rst 1 0\\n", + "4", "设置波形采样触发方式为下降沿", "cmd set_raw_trig_sel_adc2 3 0\\n", + "5", "设置波形采样触发周期", "cmd set_raw_trig_period_adc2 255 0\\n", + "6", "设置波形采样触发阈值", "cmd set_raw_trig_vth_adc2 1911 0\\n", + "7", "设置波形采样点数", "cmd set_raw_sample_len_adc2 2000 0\\n", + "8", "设置波形甄别触发方式", "cmd set_psd_trig_sel 3 0\\n", + "9", "设置波形甄别触发周期", "cmd set_psd_trig_period 100 0\\n", + "10", "设置波形甄别触发阈值", "cmd set_psd_trig_vth 1911 0\\n", + "11", "设置波形甄别门偏移", "cmd set_psd_gate_offset 12 0\\n", + "12", "设置波形甄别延迟", "cmd set_adc2_delay_num 20 0\\n", + "13", "设置波形甄别长门", "cmd set_psd_long_gate 112 0\\n", + "14", "设置波形甄别短门", "cmd set_psd_short_gate 27 0\\n", + "15", "取消复位adc", "cmd set_adc_delay_rst 0 0\\n", + "16", "取消逻辑复位", "cmd set_logic_rst 0 0\\n" + }; + + /** + * 加高压指令 + */ + public static final String DAC_UP="cmd dac_up 0 0\\n"; + /** + * 关闭高压指令 + */ + public static final String DAC_DOWN="cmd dac_down 0 0\\n"; + + /** + * 电压采样帧头 + */ + public static final String DAC_HEAD="AA55AA551ACFFC5D"; + + /** + * 波形采样帧头 + */ + public static final String WAVE_HEAD="AA55AA551ACFFC3D"; + + /** + * PSD1采样帧头 + */ + public static final String PSD1_HEAD="AA55AA551ACFFC4D"; + + /** + * PSD2采样帧头 + */ + public static final String PSD2_HEAD="F0F0A5A5"; + +} diff --git a/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java new file mode 100644 index 0000000..0732347 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java @@ -0,0 +1,59 @@ +package com.casic.missiles.netty; + +import org.springframework.stereotype.Component; + +@Component +public class InstructCode { + + /** + * 设备初始化时需要依次发送1~16号指令 + */ + public static String[] InitCodeArr = { + "1", "设置高压", "set set_voltage 4 1.2\\n", + "2", "复位adc", "cmd set_adc_delay_rst 1 0\\n", + "3", "逻辑复位", "cmd set_logic_rst 1 0\\n", + "4", "设置波形采样触发方式为下降沿", "cmd set_raw_trig_sel_adc2 3 0\\n", + "5", "设置波形采样触发周期", "cmd set_raw_trig_period_adc2 255 0\\n", + "6", "设置波形采样触发阈值", "cmd set_raw_trig_vth_adc2 1911 0\\n", + "7", "设置波形采样点数", "cmd set_raw_sample_len_adc2 2000 0\\n", + "8", "设置波形甄别触发方式", "cmd set_psd_trig_sel 3 0\\n", + "9", "设置波形甄别触发周期", "cmd set_psd_trig_period 100 0\\n", + "10", "设置波形甄别触发阈值", "cmd set_psd_trig_vth 1911 0\\n", + "11", "设置波形甄别门偏移", "cmd set_psd_gate_offset 12 0\\n", + "12", "设置波形甄别延迟", "cmd set_adc2_delay_num 20 0\\n", + "13", "设置波形甄别长门", "cmd set_psd_long_gate 112 0\\n", + "14", "设置波形甄别短门", "cmd set_psd_short_gate 27 0\\n", + "15", "取消复位adc", "cmd set_adc_delay_rst 0 0\\n", + "16", "取消逻辑复位", "cmd set_logic_rst 0 0\\n" + }; + + /** + * 加高压指令 + */ + public static final String DAC_UP="cmd dac_up 0 0\\n"; + /** + * 关闭高压指令 + */ + public static final String DAC_DOWN="cmd dac_down 0 0\\n"; + + /** + * 电压采样帧头 + */ + public static final String DAC_HEAD="AA55AA551ACFFC5D"; + + /** + * 波形采样帧头 + */ + public static final String WAVE_HEAD="AA55AA551ACFFC3D"; + + /** + * PSD1采样帧头 + */ + public static final String PSD1_HEAD="AA55AA551ACFFC4D"; + + /** + * PSD2采样帧头 + */ + public static final String PSD2_HEAD="F0F0A5A5"; + +} diff --git a/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java new file mode 100644 index 0000000..70c4e6e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java @@ -0,0 +1,89 @@ +package com.casic.missiles.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; +import java.util.concurrent.ForkJoinPool; + +@Slf4j +@Component +public class NettyClient { + +// static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); + + private final EventLoopGroup group = new NioEventLoopGroup(); + private ChannelFuture mChannelFuture = null; + private final ThreadLocal mChannel = new ThreadLocal<>(); + + @Resource + private NettyClientHandler nettyClientHandler; + + public void startClient(String host, int port) { + // Configure the client. + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioSocketChannel.class) + .option(ChannelOption.TCP_NODELAY, true)//无阻塞 + .option(ChannelOption.SO_KEEPALIVE, true)//长连接 + .handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + p.addLast("decoder", new StringDecoder()); + p.addLast("encoder", new StringEncoder()); + p.addLast(nettyClientHandler); + } + }); + + mChannelFuture = b.connect(host, port).addListener(future -> { + log.info(String.format("客户端启动成功,并监听端口:%s ", port)); + }); + } catch (Exception e) { + log.error("启动 netty 客户端出现异常", e); + } + } + + /** + * 客户端通过 Channel 对象向服务器端发送数据 + * @param data 文本数据 + */ + public void send(String data) { + try { + if (mChannel.get() == null) { + mChannel.set(mChannelFuture.channel()); + } + mChannel.get().writeAndFlush(data); + } catch (Exception e) { + log.error(this.getClass().getName().concat(".send has error"), e); + } + } + + // 客户端启动,并连上服务器端 + @PostConstruct + public void init() { + ForkJoinPool.commonPool().submit(() -> startClient("127.0.0.1", 52002)); + } + + @PreDestroy + public void destroy() { + group.shutdownGracefully(); + } + +} + diff --git a/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java new file mode 100644 index 0000000..0732347 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java @@ -0,0 +1,59 @@ +package com.casic.missiles.netty; + +import org.springframework.stereotype.Component; + +@Component +public class InstructCode { + + /** + * 设备初始化时需要依次发送1~16号指令 + */ + public static String[] InitCodeArr = { + "1", "设置高压", "set set_voltage 4 1.2\\n", + "2", "复位adc", "cmd set_adc_delay_rst 1 0\\n", + "3", "逻辑复位", "cmd set_logic_rst 1 0\\n", + "4", "设置波形采样触发方式为下降沿", "cmd set_raw_trig_sel_adc2 3 0\\n", + "5", "设置波形采样触发周期", "cmd set_raw_trig_period_adc2 255 0\\n", + "6", "设置波形采样触发阈值", "cmd set_raw_trig_vth_adc2 1911 0\\n", + "7", "设置波形采样点数", "cmd set_raw_sample_len_adc2 2000 0\\n", + "8", "设置波形甄别触发方式", "cmd set_psd_trig_sel 3 0\\n", + "9", "设置波形甄别触发周期", "cmd set_psd_trig_period 100 0\\n", + "10", "设置波形甄别触发阈值", "cmd set_psd_trig_vth 1911 0\\n", + "11", "设置波形甄别门偏移", "cmd set_psd_gate_offset 12 0\\n", + "12", "设置波形甄别延迟", "cmd set_adc2_delay_num 20 0\\n", + "13", "设置波形甄别长门", "cmd set_psd_long_gate 112 0\\n", + "14", "设置波形甄别短门", "cmd set_psd_short_gate 27 0\\n", + "15", "取消复位adc", "cmd set_adc_delay_rst 0 0\\n", + "16", "取消逻辑复位", "cmd set_logic_rst 0 0\\n" + }; + + /** + * 加高压指令 + */ + public static final String DAC_UP="cmd dac_up 0 0\\n"; + /** + * 关闭高压指令 + */ + public static final String DAC_DOWN="cmd dac_down 0 0\\n"; + + /** + * 电压采样帧头 + */ + public static final String DAC_HEAD="AA55AA551ACFFC5D"; + + /** + * 波形采样帧头 + */ + public static final String WAVE_HEAD="AA55AA551ACFFC3D"; + + /** + * PSD1采样帧头 + */ + public static final String PSD1_HEAD="AA55AA551ACFFC4D"; + + /** + * PSD2采样帧头 + */ + public static final String PSD2_HEAD="F0F0A5A5"; + +} diff --git a/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java new file mode 100644 index 0000000..70c4e6e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java @@ -0,0 +1,89 @@ +package com.casic.missiles.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; +import java.util.concurrent.ForkJoinPool; + +@Slf4j +@Component +public class NettyClient { + +// static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); + + private final EventLoopGroup group = new NioEventLoopGroup(); + private ChannelFuture mChannelFuture = null; + private final ThreadLocal mChannel = new ThreadLocal<>(); + + @Resource + private NettyClientHandler nettyClientHandler; + + public void startClient(String host, int port) { + // Configure the client. + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioSocketChannel.class) + .option(ChannelOption.TCP_NODELAY, true)//无阻塞 + .option(ChannelOption.SO_KEEPALIVE, true)//长连接 + .handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + p.addLast("decoder", new StringDecoder()); + p.addLast("encoder", new StringEncoder()); + p.addLast(nettyClientHandler); + } + }); + + mChannelFuture = b.connect(host, port).addListener(future -> { + log.info(String.format("客户端启动成功,并监听端口:%s ", port)); + }); + } catch (Exception e) { + log.error("启动 netty 客户端出现异常", e); + } + } + + /** + * 客户端通过 Channel 对象向服务器端发送数据 + * @param data 文本数据 + */ + public void send(String data) { + try { + if (mChannel.get() == null) { + mChannel.set(mChannelFuture.channel()); + } + mChannel.get().writeAndFlush(data); + } catch (Exception e) { + log.error(this.getClass().getName().concat(".send has error"), e); + } + } + + // 客户端启动,并连上服务器端 + @PostConstruct + public void init() { + ForkJoinPool.commonPool().submit(() -> startClient("127.0.0.1", 52002)); + } + + @PreDestroy + public void destroy() { + group.shutdownGracefully(); + } + +} + diff --git a/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java new file mode 100644 index 0000000..b602605 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java @@ -0,0 +1,37 @@ +package com.casic.missiles.netty; + + +import com.casic.missiles.neutron.service.INeutronOptService; +import com.casic.missiles.neutron.service.impl.NeutronOptServiceImpl; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@ChannelHandler.Sharable +@Slf4j +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + + @Autowired + private INeutronOptService neutronOptService; + + // 服务器端读取到 客户端发送过来的数据,然后通过 Channel 回写数据 + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + log.info(String.format("客户端读取到从服务器端:%s 发送过来的数据:%s", ctx.channel().remoteAddress(), msg.toString())); +// ctx.channel().writeAndFlush(String.format("server write:%s", msg)); + //解析数据 + neutronOptService.analysis(msg.toString()); + } + + // 捕获到异常的处理 + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + cause.printStackTrace(); + ctx.close(); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java new file mode 100644 index 0000000..0732347 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java @@ -0,0 +1,59 @@ +package com.casic.missiles.netty; + +import org.springframework.stereotype.Component; + +@Component +public class InstructCode { + + /** + * 设备初始化时需要依次发送1~16号指令 + */ + public static String[] InitCodeArr = { + "1", "设置高压", "set set_voltage 4 1.2\\n", + "2", "复位adc", "cmd set_adc_delay_rst 1 0\\n", + "3", "逻辑复位", "cmd set_logic_rst 1 0\\n", + "4", "设置波形采样触发方式为下降沿", "cmd set_raw_trig_sel_adc2 3 0\\n", + "5", "设置波形采样触发周期", "cmd set_raw_trig_period_adc2 255 0\\n", + "6", "设置波形采样触发阈值", "cmd set_raw_trig_vth_adc2 1911 0\\n", + "7", "设置波形采样点数", "cmd set_raw_sample_len_adc2 2000 0\\n", + "8", "设置波形甄别触发方式", "cmd set_psd_trig_sel 3 0\\n", + "9", "设置波形甄别触发周期", "cmd set_psd_trig_period 100 0\\n", + "10", "设置波形甄别触发阈值", "cmd set_psd_trig_vth 1911 0\\n", + "11", "设置波形甄别门偏移", "cmd set_psd_gate_offset 12 0\\n", + "12", "设置波形甄别延迟", "cmd set_adc2_delay_num 20 0\\n", + "13", "设置波形甄别长门", "cmd set_psd_long_gate 112 0\\n", + "14", "设置波形甄别短门", "cmd set_psd_short_gate 27 0\\n", + "15", "取消复位adc", "cmd set_adc_delay_rst 0 0\\n", + "16", "取消逻辑复位", "cmd set_logic_rst 0 0\\n" + }; + + /** + * 加高压指令 + */ + public static final String DAC_UP="cmd dac_up 0 0\\n"; + /** + * 关闭高压指令 + */ + public static final String DAC_DOWN="cmd dac_down 0 0\\n"; + + /** + * 电压采样帧头 + */ + public static final String DAC_HEAD="AA55AA551ACFFC5D"; + + /** + * 波形采样帧头 + */ + public static final String WAVE_HEAD="AA55AA551ACFFC3D"; + + /** + * PSD1采样帧头 + */ + public static final String PSD1_HEAD="AA55AA551ACFFC4D"; + + /** + * PSD2采样帧头 + */ + public static final String PSD2_HEAD="F0F0A5A5"; + +} diff --git a/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java new file mode 100644 index 0000000..70c4e6e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java @@ -0,0 +1,89 @@ +package com.casic.missiles.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; +import java.util.concurrent.ForkJoinPool; + +@Slf4j +@Component +public class NettyClient { + +// static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); + + private final EventLoopGroup group = new NioEventLoopGroup(); + private ChannelFuture mChannelFuture = null; + private final ThreadLocal mChannel = new ThreadLocal<>(); + + @Resource + private NettyClientHandler nettyClientHandler; + + public void startClient(String host, int port) { + // Configure the client. + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioSocketChannel.class) + .option(ChannelOption.TCP_NODELAY, true)//无阻塞 + .option(ChannelOption.SO_KEEPALIVE, true)//长连接 + .handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + p.addLast("decoder", new StringDecoder()); + p.addLast("encoder", new StringEncoder()); + p.addLast(nettyClientHandler); + } + }); + + mChannelFuture = b.connect(host, port).addListener(future -> { + log.info(String.format("客户端启动成功,并监听端口:%s ", port)); + }); + } catch (Exception e) { + log.error("启动 netty 客户端出现异常", e); + } + } + + /** + * 客户端通过 Channel 对象向服务器端发送数据 + * @param data 文本数据 + */ + public void send(String data) { + try { + if (mChannel.get() == null) { + mChannel.set(mChannelFuture.channel()); + } + mChannel.get().writeAndFlush(data); + } catch (Exception e) { + log.error(this.getClass().getName().concat(".send has error"), e); + } + } + + // 客户端启动,并连上服务器端 + @PostConstruct + public void init() { + ForkJoinPool.commonPool().submit(() -> startClient("127.0.0.1", 52002)); + } + + @PreDestroy + public void destroy() { + group.shutdownGracefully(); + } + +} + diff --git a/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java new file mode 100644 index 0000000..b602605 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java @@ -0,0 +1,37 @@ +package com.casic.missiles.netty; + + +import com.casic.missiles.neutron.service.INeutronOptService; +import com.casic.missiles.neutron.service.impl.NeutronOptServiceImpl; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@ChannelHandler.Sharable +@Slf4j +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + + @Autowired + private INeutronOptService neutronOptService; + + // 服务器端读取到 客户端发送过来的数据,然后通过 Channel 回写数据 + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + log.info(String.format("客户端读取到从服务器端:%s 发送过来的数据:%s", ctx.channel().remoteAddress(), msg.toString())); +// ctx.channel().writeAndFlush(String.format("server write:%s", msg)); + //解析数据 + neutronOptService.analysis(msg.toString()); + } + + // 捕获到异常的处理 + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + cause.printStackTrace(); + ctx.close(); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/neutron/controller/NeutronController.java b/casic-server/src/main/java/com/casic/missiles/neutron/controller/NeutronController.java new file mode 100644 index 0000000..c373083 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/neutron/controller/NeutronController.java @@ -0,0 +1,33 @@ +package com.casic.missiles.neutron.controller; + + +import cn.hutool.core.util.ObjectUtil; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.neutron.service.INeutronOptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping("/Neutron") +public class NeutronController { + + @Autowired + private INeutronOptService neutronOptService; + + + /** + * 中子源控制 + * + * @param command 控制指令类型(start-加压开始工作,stop-退高压,停止工作) + */ + @RequestMapping("/control") + @ResponseBody + public Object control(String command) { + neutronOptService.control(command); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java new file mode 100644 index 0000000..0732347 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java @@ -0,0 +1,59 @@ +package com.casic.missiles.netty; + +import org.springframework.stereotype.Component; + +@Component +public class InstructCode { + + /** + * 设备初始化时需要依次发送1~16号指令 + */ + public static String[] InitCodeArr = { + "1", "设置高压", "set set_voltage 4 1.2\\n", + "2", "复位adc", "cmd set_adc_delay_rst 1 0\\n", + "3", "逻辑复位", "cmd set_logic_rst 1 0\\n", + "4", "设置波形采样触发方式为下降沿", "cmd set_raw_trig_sel_adc2 3 0\\n", + "5", "设置波形采样触发周期", "cmd set_raw_trig_period_adc2 255 0\\n", + "6", "设置波形采样触发阈值", "cmd set_raw_trig_vth_adc2 1911 0\\n", + "7", "设置波形采样点数", "cmd set_raw_sample_len_adc2 2000 0\\n", + "8", "设置波形甄别触发方式", "cmd set_psd_trig_sel 3 0\\n", + "9", "设置波形甄别触发周期", "cmd set_psd_trig_period 100 0\\n", + "10", "设置波形甄别触发阈值", "cmd set_psd_trig_vth 1911 0\\n", + "11", "设置波形甄别门偏移", "cmd set_psd_gate_offset 12 0\\n", + "12", "设置波形甄别延迟", "cmd set_adc2_delay_num 20 0\\n", + "13", "设置波形甄别长门", "cmd set_psd_long_gate 112 0\\n", + "14", "设置波形甄别短门", "cmd set_psd_short_gate 27 0\\n", + "15", "取消复位adc", "cmd set_adc_delay_rst 0 0\\n", + "16", "取消逻辑复位", "cmd set_logic_rst 0 0\\n" + }; + + /** + * 加高压指令 + */ + public static final String DAC_UP="cmd dac_up 0 0\\n"; + /** + * 关闭高压指令 + */ + public static final String DAC_DOWN="cmd dac_down 0 0\\n"; + + /** + * 电压采样帧头 + */ + public static final String DAC_HEAD="AA55AA551ACFFC5D"; + + /** + * 波形采样帧头 + */ + public static final String WAVE_HEAD="AA55AA551ACFFC3D"; + + /** + * PSD1采样帧头 + */ + public static final String PSD1_HEAD="AA55AA551ACFFC4D"; + + /** + * PSD2采样帧头 + */ + public static final String PSD2_HEAD="F0F0A5A5"; + +} diff --git a/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java new file mode 100644 index 0000000..70c4e6e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java @@ -0,0 +1,89 @@ +package com.casic.missiles.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; +import java.util.concurrent.ForkJoinPool; + +@Slf4j +@Component +public class NettyClient { + +// static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); + + private final EventLoopGroup group = new NioEventLoopGroup(); + private ChannelFuture mChannelFuture = null; + private final ThreadLocal mChannel = new ThreadLocal<>(); + + @Resource + private NettyClientHandler nettyClientHandler; + + public void startClient(String host, int port) { + // Configure the client. + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioSocketChannel.class) + .option(ChannelOption.TCP_NODELAY, true)//无阻塞 + .option(ChannelOption.SO_KEEPALIVE, true)//长连接 + .handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + p.addLast("decoder", new StringDecoder()); + p.addLast("encoder", new StringEncoder()); + p.addLast(nettyClientHandler); + } + }); + + mChannelFuture = b.connect(host, port).addListener(future -> { + log.info(String.format("客户端启动成功,并监听端口:%s ", port)); + }); + } catch (Exception e) { + log.error("启动 netty 客户端出现异常", e); + } + } + + /** + * 客户端通过 Channel 对象向服务器端发送数据 + * @param data 文本数据 + */ + public void send(String data) { + try { + if (mChannel.get() == null) { + mChannel.set(mChannelFuture.channel()); + } + mChannel.get().writeAndFlush(data); + } catch (Exception e) { + log.error(this.getClass().getName().concat(".send has error"), e); + } + } + + // 客户端启动,并连上服务器端 + @PostConstruct + public void init() { + ForkJoinPool.commonPool().submit(() -> startClient("127.0.0.1", 52002)); + } + + @PreDestroy + public void destroy() { + group.shutdownGracefully(); + } + +} + diff --git a/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java new file mode 100644 index 0000000..b602605 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java @@ -0,0 +1,37 @@ +package com.casic.missiles.netty; + + +import com.casic.missiles.neutron.service.INeutronOptService; +import com.casic.missiles.neutron.service.impl.NeutronOptServiceImpl; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@ChannelHandler.Sharable +@Slf4j +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + + @Autowired + private INeutronOptService neutronOptService; + + // 服务器端读取到 客户端发送过来的数据,然后通过 Channel 回写数据 + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + log.info(String.format("客户端读取到从服务器端:%s 发送过来的数据:%s", ctx.channel().remoteAddress(), msg.toString())); +// ctx.channel().writeAndFlush(String.format("server write:%s", msg)); + //解析数据 + neutronOptService.analysis(msg.toString()); + } + + // 捕获到异常的处理 + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + cause.printStackTrace(); + ctx.close(); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/neutron/controller/NeutronController.java b/casic-server/src/main/java/com/casic/missiles/neutron/controller/NeutronController.java new file mode 100644 index 0000000..c373083 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/neutron/controller/NeutronController.java @@ -0,0 +1,33 @@ +package com.casic.missiles.neutron.controller; + + +import cn.hutool.core.util.ObjectUtil; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.neutron.service.INeutronOptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping("/Neutron") +public class NeutronController { + + @Autowired + private INeutronOptService neutronOptService; + + + /** + * 中子源控制 + * + * @param command 控制指令类型(start-加压开始工作,stop-退高压,停止工作) + */ + @RequestMapping("/control") + @ResponseBody + public Object control(String command) { + neutronOptService.control(command); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/neutron/service/INeutronOptService.java b/casic-server/src/main/java/com/casic/missiles/neutron/service/INeutronOptService.java index c7e8dfd..aad4ab7 100644 --- a/casic-server/src/main/java/com/casic/missiles/neutron/service/INeutronOptService.java +++ b/casic-server/src/main/java/com/casic/missiles/neutron/service/INeutronOptService.java @@ -13,7 +13,7 @@ void deviceInit(); /** - * No.2 加压 + * No.2 加压,开始工作 */ void pressurize(); @@ -21,6 +21,13 @@ * No.3 解析 * 设备会在tcp上 上报数据,读取后进行解析 */ - void analysis(); + void analysis(String msg); + + /** + * No.4 退高压,停止工作 + */ + void depress(); + + void control(String command); } diff --git a/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java new file mode 100644 index 0000000..0732347 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/InstructCode.java @@ -0,0 +1,59 @@ +package com.casic.missiles.netty; + +import org.springframework.stereotype.Component; + +@Component +public class InstructCode { + + /** + * 设备初始化时需要依次发送1~16号指令 + */ + public static String[] InitCodeArr = { + "1", "设置高压", "set set_voltage 4 1.2\\n", + "2", "复位adc", "cmd set_adc_delay_rst 1 0\\n", + "3", "逻辑复位", "cmd set_logic_rst 1 0\\n", + "4", "设置波形采样触发方式为下降沿", "cmd set_raw_trig_sel_adc2 3 0\\n", + "5", "设置波形采样触发周期", "cmd set_raw_trig_period_adc2 255 0\\n", + "6", "设置波形采样触发阈值", "cmd set_raw_trig_vth_adc2 1911 0\\n", + "7", "设置波形采样点数", "cmd set_raw_sample_len_adc2 2000 0\\n", + "8", "设置波形甄别触发方式", "cmd set_psd_trig_sel 3 0\\n", + "9", "设置波形甄别触发周期", "cmd set_psd_trig_period 100 0\\n", + "10", "设置波形甄别触发阈值", "cmd set_psd_trig_vth 1911 0\\n", + "11", "设置波形甄别门偏移", "cmd set_psd_gate_offset 12 0\\n", + "12", "设置波形甄别延迟", "cmd set_adc2_delay_num 20 0\\n", + "13", "设置波形甄别长门", "cmd set_psd_long_gate 112 0\\n", + "14", "设置波形甄别短门", "cmd set_psd_short_gate 27 0\\n", + "15", "取消复位adc", "cmd set_adc_delay_rst 0 0\\n", + "16", "取消逻辑复位", "cmd set_logic_rst 0 0\\n" + }; + + /** + * 加高压指令 + */ + public static final String DAC_UP="cmd dac_up 0 0\\n"; + /** + * 关闭高压指令 + */ + public static final String DAC_DOWN="cmd dac_down 0 0\\n"; + + /** + * 电压采样帧头 + */ + public static final String DAC_HEAD="AA55AA551ACFFC5D"; + + /** + * 波形采样帧头 + */ + public static final String WAVE_HEAD="AA55AA551ACFFC3D"; + + /** + * PSD1采样帧头 + */ + public static final String PSD1_HEAD="AA55AA551ACFFC4D"; + + /** + * PSD2采样帧头 + */ + public static final String PSD2_HEAD="F0F0A5A5"; + +} diff --git a/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java new file mode 100644 index 0000000..70c4e6e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/NettyClient.java @@ -0,0 +1,89 @@ +package com.casic.missiles.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; +import java.util.concurrent.ForkJoinPool; + +@Slf4j +@Component +public class NettyClient { + +// static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); + + private final EventLoopGroup group = new NioEventLoopGroup(); + private ChannelFuture mChannelFuture = null; + private final ThreadLocal mChannel = new ThreadLocal<>(); + + @Resource + private NettyClientHandler nettyClientHandler; + + public void startClient(String host, int port) { + // Configure the client. + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioSocketChannel.class) + .option(ChannelOption.TCP_NODELAY, true)//无阻塞 + .option(ChannelOption.SO_KEEPALIVE, true)//长连接 + .handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + p.addLast("decoder", new StringDecoder()); + p.addLast("encoder", new StringEncoder()); + p.addLast(nettyClientHandler); + } + }); + + mChannelFuture = b.connect(host, port).addListener(future -> { + log.info(String.format("客户端启动成功,并监听端口:%s ", port)); + }); + } catch (Exception e) { + log.error("启动 netty 客户端出现异常", e); + } + } + + /** + * 客户端通过 Channel 对象向服务器端发送数据 + * @param data 文本数据 + */ + public void send(String data) { + try { + if (mChannel.get() == null) { + mChannel.set(mChannelFuture.channel()); + } + mChannel.get().writeAndFlush(data); + } catch (Exception e) { + log.error(this.getClass().getName().concat(".send has error"), e); + } + } + + // 客户端启动,并连上服务器端 + @PostConstruct + public void init() { + ForkJoinPool.commonPool().submit(() -> startClient("127.0.0.1", 52002)); + } + + @PreDestroy + public void destroy() { + group.shutdownGracefully(); + } + +} + diff --git a/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java new file mode 100644 index 0000000..b602605 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/netty/NettyClientHandler.java @@ -0,0 +1,37 @@ +package com.casic.missiles.netty; + + +import com.casic.missiles.neutron.service.INeutronOptService; +import com.casic.missiles.neutron.service.impl.NeutronOptServiceImpl; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@ChannelHandler.Sharable +@Slf4j +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + + @Autowired + private INeutronOptService neutronOptService; + + // 服务器端读取到 客户端发送过来的数据,然后通过 Channel 回写数据 + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + log.info(String.format("客户端读取到从服务器端:%s 发送过来的数据:%s", ctx.channel().remoteAddress(), msg.toString())); +// ctx.channel().writeAndFlush(String.format("server write:%s", msg)); + //解析数据 + neutronOptService.analysis(msg.toString()); + } + + // 捕获到异常的处理 + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + cause.printStackTrace(); + ctx.close(); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/neutron/controller/NeutronController.java b/casic-server/src/main/java/com/casic/missiles/neutron/controller/NeutronController.java new file mode 100644 index 0000000..c373083 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/neutron/controller/NeutronController.java @@ -0,0 +1,33 @@ +package com.casic.missiles.neutron.controller; + + +import cn.hutool.core.util.ObjectUtil; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.neutron.service.INeutronOptService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping("/Neutron") +public class NeutronController { + + @Autowired + private INeutronOptService neutronOptService; + + + /** + * 中子源控制 + * + * @param command 控制指令类型(start-加压开始工作,stop-退高压,停止工作) + */ + @RequestMapping("/control") + @ResponseBody + public Object control(String command) { + neutronOptService.control(command); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/neutron/service/INeutronOptService.java b/casic-server/src/main/java/com/casic/missiles/neutron/service/INeutronOptService.java index c7e8dfd..aad4ab7 100644 --- a/casic-server/src/main/java/com/casic/missiles/neutron/service/INeutronOptService.java +++ b/casic-server/src/main/java/com/casic/missiles/neutron/service/INeutronOptService.java @@ -13,7 +13,7 @@ void deviceInit(); /** - * No.2 加压 + * No.2 加压,开始工作 */ void pressurize(); @@ -21,6 +21,13 @@ * No.3 解析 * 设备会在tcp上 上报数据,读取后进行解析 */ - void analysis(); + void analysis(String msg); + + /** + * No.4 退高压,停止工作 + */ + void depress(); + + void control(String command); } diff --git a/casic-server/src/main/java/com/casic/missiles/neutron/service/impl/NeutronOptServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/neutron/service/impl/NeutronOptServiceImpl.java new file mode 100644 index 0000000..7243ea6 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/neutron/service/impl/NeutronOptServiceImpl.java @@ -0,0 +1,73 @@ +package com.casic.missiles.neutron.service.impl; + +import com.casic.missiles.netty.InstructCode; +import com.casic.missiles.netty.NettyClient; +import com.casic.missiles.neutron.service.INeutronOptService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + + +@Service +public class NeutronOptServiceImpl implements INeutronOptService { + + @Resource + private NettyClient nettyClient; + + @Override + public void deviceInit() { + for (int i = 1; i <= InstructCode.InitCodeArr.length / 3; i++) { + try { + nettyClient.send(InstructCode.InitCodeArr[i * 3 - 1]); + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + @Override + public void pressurize() { + nettyClient.send(InstructCode.DAC_UP); + } + + + @Override + public void analysis(String msg) { + + if(msg.indexOf(InstructCode.PSD1_HEAD)==0){ + //截取psd流数据 + msg=msg.substring(24); + if(msg.indexOf(InstructCode.PSD2_HEAD)==0&&msg.length()>=64){ + String gateOff= msg.substring(16,20); + String baseline= msg.substring(20,24); + String shortGate= msg.substring(24,28); + String longGate= msg.substring(28,32); + String qlong= msg.substring(48,56); + String qshort= msg.substring(56,64); + //toDo:算法计算 + } + } + + } + + @Override + public void depress() { + nettyClient.send(InstructCode.DAC_DOWN); + } + + @Override + public void control(String command) { + switch (command) { + case "start": + this.pressurize(); + break; + case "stop": + this.depress(); + break; + case "off": + default: + break; + } + } +}