|
@@ -0,0 +1,115 @@
|
|
|
+package com.gzlh.device.car.client;
|
|
|
+
|
|
|
+import com.gzlh.bus.EventConfig;
|
|
|
+import com.gzlh.config.dto.SerialSetting;
|
|
|
+import com.gzlh.config.netty.NettyDecoder;
|
|
|
+import com.gzlh.utils.XorUtils;
|
|
|
+import io.netty.bootstrap.Bootstrap;
|
|
|
+import io.netty.buffer.ByteBuf;
|
|
|
+import io.netty.buffer.Unpooled;
|
|
|
+import io.netty.channel.*;
|
|
|
+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.StringEncoder;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.context.annotation.Bean;
|
|
|
+import org.springframework.context.annotation.Configuration;
|
|
|
+
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+@Configuration
|
|
|
+@Slf4j
|
|
|
+public class CarNettyConfig {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private CarClientHandler carClientHandler;
|
|
|
+
|
|
|
+ private Channel channel;
|
|
|
+
|
|
|
+ @Bean("carBootstrap")
|
|
|
+ public Bootstrap bootstrap() {
|
|
|
+ SerialSetting serialSetting= EventConfig.serialSetting;
|
|
|
+ String host = serialSetting.getHost();
|
|
|
+ int port = serialSetting.getCar().getPort();
|
|
|
+ if (serialSetting.getCar().getEnable()) {
|
|
|
+ log.info("初始化 car:{},{}", host, port);
|
|
|
+ }
|
|
|
+ EventLoopGroup group = new NioEventLoopGroup();
|
|
|
+ return new Bootstrap()
|
|
|
+ .group(group)
|
|
|
+ .channel(NioSocketChannel.class)
|
|
|
+ .remoteAddress(host, port)
|
|
|
+ .option(ChannelOption.SO_KEEPALIVE, true)
|
|
|
+ .handler(new ChannelInitializer<SocketChannel>() {
|
|
|
+ @Override
|
|
|
+ protected void initChannel(SocketChannel ch) {
|
|
|
+ try {
|
|
|
+ ChannelPipeline pipeline = ch.pipeline();
|
|
|
+ pipeline.addLast( new NettyDecoder());
|
|
|
+ pipeline.addLast( new StringEncoder(StandardCharsets.UTF_8));
|
|
|
+ pipeline.addLast("handler", carClientHandler);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info("error connect:{}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean("carClientHandler")
|
|
|
+ public CarClientHandler carClientHandler() {
|
|
|
+ return new CarClientHandler(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void connect() {
|
|
|
+ SerialSetting serialSetting= EventConfig.serialSetting;
|
|
|
+ String host = serialSetting.getHost();
|
|
|
+ int port = serialSetting.getCar().getPort();
|
|
|
+ ChannelFuture future = bootstrap().connect();
|
|
|
+ future.addListener((ChannelFutureListener) future1 -> {
|
|
|
+ if (future1.isSuccess()) {
|
|
|
+ channel = future1.channel();
|
|
|
+ log.info("car 串口服务器连接成功,{},{}", host, port);
|
|
|
+ } else {
|
|
|
+ log.error("-------------car 连接服务器失败,{},{}-----------,进行重连", host, port);
|
|
|
+ future1.channel().eventLoop().schedule(this::connect, 5, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ try {
|
|
|
+ future.channel().closeFuture().sync();
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void send(String message) {
|
|
|
+ if (channel != null && channel.isActive()) {
|
|
|
+ ByteBuf bufff = Unpooled.buffer();
|
|
|
+ bufff.writeBytes(XorUtils.hexString2Bytes(message));
|
|
|
+ channel.writeAndFlush(bufff);
|
|
|
+ } else {
|
|
|
+ log.error("未建立连接,无法发送消息");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void close() {
|
|
|
+ if (channel != null) {
|
|
|
+ channel.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private byte[] hexStringToByteArray(String hexString) {
|
|
|
+
|
|
|
+ int len = hexString.length();
|
|
|
+ byte[] data = new byte[len / 2];
|
|
|
+ for (int i = 0; i < len; i += 2) {
|
|
|
+ data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
|
|
|
+ + Character.digit(hexString.charAt(i+1), 16));
|
|
|
+ }
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|