From 6b7e0bfa3300a5745e0b8f94bd7b04ad62b448a4 Mon Sep 17 00:00:00 2001 From: yuchao1990 <757143422@qq.com> Date: Sun, 28 Jun 2020 08:57:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=A9=E5=B1=95=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modbus-server/pom.xml | 73 +++ .../SarnathModbusServerApplication.java | 30 ++ .../modbusserver/dtuutils/BitConverter.java | 420 ++++++++++++++++++ .../modbusserver/dtuutils/DTUServer.java | 48 ++ .../dtuutils/DTUServerHandler.java | 137 ++++++ modbus-server/src/main/resources/banner.txt | 8 + .../src/main/resources/bootstrap.yml | 24 + modbus-server/src/main/resources/logback.xml | 74 +++ pom.xml | 27 +- ruoyi-api/ruoyi-api-system/pom.xml | 8 +- .../ruoyi/common/core/utils/BitConverter.java | 380 ++++++++++++++++ .../gateway/RuoYiGatewayApplication.java | 6 +- ruoyi-modules/ruoyi-system/pom.xml | 30 +- .../system/controller/SysUserController.java | 1 + ruoyi-visual/hystrix-dashboard/pom.xml | 67 +++ .../HystrixDashBoardApplication.java | 22 + .../src/main/resources/banner.txt | 8 + .../src/main/resources/bootstrap.yml | 24 + ruoyi-visual/pom.xml | 1 + 19 files changed, 1353 insertions(+), 35 deletions(-) create mode 100644 modbus-server/pom.xml create mode 100644 modbus-server/src/main/java/com/sarnath/modbusserver/SarnathModbusServerApplication.java create mode 100644 modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/BitConverter.java create mode 100644 modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/DTUServer.java create mode 100644 modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/DTUServerHandler.java create mode 100644 modbus-server/src/main/resources/banner.txt create mode 100644 modbus-server/src/main/resources/bootstrap.yml create mode 100644 modbus-server/src/main/resources/logback.xml create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/BitConverter.java create mode 100644 ruoyi-visual/hystrix-dashboard/pom.xml create mode 100644 ruoyi-visual/hystrix-dashboard/src/main/java/com/sarnath/hystrix/dashboard/HystrixDashBoardApplication.java create mode 100644 ruoyi-visual/hystrix-dashboard/src/main/resources/banner.txt create mode 100644 ruoyi-visual/hystrix-dashboard/src/main/resources/bootstrap.yml diff --git a/modbus-server/pom.xml b/modbus-server/pom.xml new file mode 100644 index 00000000..ea4e34fb --- /dev/null +++ b/modbus-server/pom.xml @@ -0,0 +1,73 @@ + + + + ruoyi + com.ruoyi + 2.0.0 + + 4.0.0 + + modbus-server + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-web + + + + + io.springfox + springfox-swagger-ui + ${swagger.fox.version} + + + + com.ruoyi + ruoyi-common-swagger + + + + io.netty + netty-all + 4.1.50.Final + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + diff --git a/modbus-server/src/main/java/com/sarnath/modbusserver/SarnathModbusServerApplication.java b/modbus-server/src/main/java/com/sarnath/modbusserver/SarnathModbusServerApplication.java new file mode 100644 index 00000000..1b3b4d0b --- /dev/null +++ b/modbus-server/src/main/java/com/sarnath/modbusserver/SarnathModbusServerApplication.java @@ -0,0 +1,30 @@ +package com.sarnath.modbusserver; + +import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2; +import com.sarnath.modbusserver.dtuutils.DTUServer; +import org.springframework.boot.SpringApplication; +import org.springframework.cloud.client.SpringCloudApplication; + +@EnableCustomSwagger2 +@SpringCloudApplication +public class SarnathModbusServerApplication +{ + public static void main(String[] args) + { + SpringApplication.run(SarnathModbusServerApplication.class, args); + + + new Thread(()->{ + DTUServer.Start(); + }).start(); + System.out.println("(♥◠‿◠)ノ゙ Modbus服务端模块启动成功 ლ(´ڡ`ლ)゙ \n" + + "____.___._________ \n" + + "\\__ | |\\_ ___ \\ \n" + + " / | |/ \\ \\/ \n" + + " \\____ |\\ \\____\n" + + " / ______| \\______ /\n" + + " \\/ \\/ "); + + + } +} diff --git a/modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/BitConverter.java b/modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/BitConverter.java new file mode 100644 index 00000000..b11a6474 --- /dev/null +++ b/modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/BitConverter.java @@ -0,0 +1,420 @@ +package com.sarnath.modbusserver.dtuutils; + +import java.nio.ByteOrder; +import java.nio.charset.Charset; + +/** + * 数字转字节数组工具类 + */ +public class BitConverter { + + /** + * 以字节数组的形式返回指定的布尔值 + * @param data 一个布尔值 + * @return 长度为 1 的字节数组 + */ + public static byte[] getBytes(boolean data) { + byte[] bytes = new byte[1]; + bytes[0] = (byte) (data ? 1 : 0); + return bytes; + } + + /** + * 以字节数组的形式返回指定的 16 位有符号整数值 + * @param data 要转换的数字 + * @return 长度为 2 的字节数组 + */ + public static byte[] getBytes(short data) { + byte[] bytes = new byte[2]; + if (isLittleEndian()) { + bytes[0] = (byte) (data & 0xff); + bytes[1] = (byte) ((data & 0xff00) >> 8); + } else { + bytes[1] = (byte) (data & 0xff); + bytes[0] = (byte) ((data & 0xff00) >> 8); + } + return bytes; + } + + /** + * 以字节数组的形式返回指定的 Unicode 字符值 + * @param data 要转换的字符 + * @return 长度为 2 的字节数组 + */ + public static byte[] getBytes(char data) { + byte[] bytes = new byte[2]; + if (isLittleEndian()) { + bytes[0] = (byte) (data); + bytes[1] = (byte) (data >> 8); + } else { + bytes[1] = (byte) (data); + bytes[0] = (byte) (data >> 8); + } + return bytes; + } + + /** + * 以字节数组的形式返回指定的 32 位有符号整数值 + * @param data 要转换的数字 + * @return 长度为 4 的字节数组 + */ + public static byte[] getBytes(int data) { + byte[] bytes = new byte[4]; + if (isLittleEndian()) { + bytes[0] = (byte) (data & 0xff); + bytes[1] = (byte) ((data & 0xff00) >> 8); + bytes[2] = (byte) ((data & 0xff0000) >> 16); + bytes[3] = (byte) ((data & 0xff000000) >> 24); + } else { + bytes[3] = (byte) (data & 0xff); + bytes[2] = (byte) ((data & 0xff00) >> 8); + bytes[1] = (byte) ((data & 0xff0000) >> 16); + bytes[0] = (byte) ((data & 0xff000000) >> 24); + } + return bytes; + } + + /** + * 以字节数组的形式返回指定的 64 位有符号整数值 + * @param data 要转换的数字 + * @return 长度为 8 的字节数组 + */ + public static byte[] getBytes(long data) { + byte[] bytes = new byte[8]; + if (isLittleEndian()) { + bytes[0] = (byte) (data & 0xff); + bytes[1] = (byte) ((data >> 8) & 0xff); + bytes[2] = (byte) ((data >> 16) & 0xff); + bytes[3] = (byte) ((data >> 24) & 0xff); + bytes[4] = (byte) ((data >> 32) & 0xff); + bytes[5] = (byte) ((data >> 40) & 0xff); + bytes[6] = (byte) ((data >> 48) & 0xff); + bytes[7] = (byte) ((data >> 56) & 0xff); + } else { + bytes[7] = (byte) (data & 0xff); + bytes[6] = (byte) ((data >> 8) & 0xff); + bytes[5] = (byte) ((data >> 16) & 0xff); + bytes[4] = (byte) ((data >> 24) & 0xff); + bytes[3] = (byte) ((data >> 32) & 0xff); + bytes[2] = (byte) ((data >> 40) & 0xff); + bytes[1] = (byte) ((data >> 48) & 0xff); + bytes[0] = (byte) ((data >> 56) & 0xff); + } + return bytes; + } + + /** + * 以字节数组的形式返回指定的单精度浮点值 + * @param data 要转换的数字 + * @return 长度为 4 的字节数组 + */ + public static byte[] getBytes(float data) { + return getBytes(Float.floatToIntBits(data)); + } + + /** + * 以字节数组的形式返回指定的双精度浮点值 + * @param data 要转换的数字 + * @return 长度为 8 的字节数组 + */ + public static byte[] getBytes(double data) { + return getBytes(Double.doubleToLongBits(data)); + } + + /** + * 将指定字符串中的所有字符编码为一个字节序列 + * @param data 包含要编码的字符的字符串 + * @return 一个字节数组,包含对指定的字符集进行编码的结果 + */ + public static byte[] getBytes(String data) { + return data.getBytes(Charset.forName("UTF-8")); + } + + /** + * 将指定字符串中的所有字符编码为一个字节序列 + * @param data 包含要编码的字符的字符串 + * @param charsetName 字符集编码 + * @return 一个字节数组,包含对指定的字符集进行编码的结果 + */ + public static byte[] getBytes(String data, String charsetName) { + return data.getBytes(Charset.forName(charsetName)); + } + + /** + * 返回由字节数组转换来的布尔值 + * @param bytes 字节数组 + * @return 布尔值 + */ + public static boolean toBoolean(byte[] bytes) { + return bytes[0] == 0 ? false : true; + } + + /** + * 返回由字节数组中的指定的一个字节转换来的布尔值 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 布尔值 + */ + public static boolean toBoolean(byte[] bytes, int startIndex) { + return toBoolean(copyFrom(bytes, startIndex, 1)); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + if (isLittleEndian()) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + } else { + return (short) ((0xff & bytes[1]) | (0xff00 & (bytes[0] << 8))); + } + } + + /** + * 无符号short整数转换为2字节的byte数组 + * + * @param s + * short整数 + * @return byte数组 + */ + public static byte[] unsignedShortToByte2(int s) { + byte[] targets = new byte[2]; + targets[0] = (byte) (s >> 8 & 0xFF); + targets[1] = (byte) (s & 0xFF); + return targets; + } + + /** + * byte数组转换为无符号short整数 + * + * @param bytes + * byte数组 + * @return short整数 + */ + public static int byte2ToUnsignedShort(byte[] bytes) { + return byte2ToUnsignedShort(bytes, 0); + } + + /** + * byte数组转换为无符号short整数 + * + * @param bytes + * byte数组 + * @param off + * 开始位置 + * @return short整数 + */ + public static int byte2ToUnsignedShort(byte[] bytes, int off) { + int high = bytes[off]; + int low = bytes[off + 1]; + return (high << 8 & 0xFF00) | (low & 0xFF); + } + + /** + * 返回由字节数组中的指定的两个字节转换来的 16 位有符号整数 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes, int startIndex) { + return toShort(copyFrom(bytes, startIndex, 2)); + } + + /** + * 返回由字节数组转换来的 Unicode 字符 + * @param bytes 字节数组 + * @return 由两个字节构成的字符 + */ + public static char toChar(byte[] bytes) { + if (isLittleEndian()) { + return (char) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + } else { + return (char) ((0xff & bytes[1]) | (0xff00 & (bytes[0] << 8))); + } + } + + /** + * 返回由字节数组中的指定的两个字节转换来的 Unicode 字符 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由两个字节构成的字符 + */ + public static char toChar(byte[] bytes, int startIndex) { + return toChar(copyFrom(bytes, startIndex, 2)); + } + + /** + * 返回由字节数组转换来的 32 位有符号整数 + * @param bytes 字节数组 + * @return 由四个字节构成的 32 位有符号整数 + */ + public static int toInt(byte[] bytes) { + if (isLittleEndian()) { + return (0xff & bytes[0]) + | (0xff00 & (bytes[1] << 8)) + | (0xff0000 & (bytes[2] << 16)) + | (0xff000000 & (bytes[3] << 24)); + } else { + return (0xff & bytes[3]) + | (0xff00 & (bytes[2] << 8)) + | (0xff0000 & (bytes[1] << 16)) + | (0xff000000 & (bytes[0] << 24)); + } + } + + /** + * 返回由字节数组中的指定的四个字节转换来的 32 位有符号整数 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由四个字节构成的 32 位有符号整数 + */ + public static int toInt(byte[] bytes, int startIndex) { + return toInt(copyFrom(bytes, startIndex, 4)); + } + + /** + * 返回由字节数组转换来的 64 位有符号整数 + * @param bytes 字节数组 + * @return 由八个字节构成的 64 位有符号整数 + */ + public static long toLong(byte[] bytes) { + if (isLittleEndian()) { + return (0xffL & (long) bytes[0]) + | (0xff00L & ((long) bytes[1] << 8)) + | (0xff0000L & ((long) bytes[2] << 16)) + | (0xff000000L & ((long) bytes[3] << 24)) + | (0xff00000000L & ((long) bytes[4] << 32)) + | (0xff0000000000L & ((long) bytes[5] << 40)) + | (0xff000000000000L & ((long) bytes[6] << 48)) + | (0xff00000000000000L & ((long) bytes[7] << 56)); + } else { + return (0xffL & (long) bytes[7]) + | (0xff00L & ((long) bytes[6] << 8)) + | (0xff0000L & ((long) bytes[5] << 16)) + | (0xff000000L & ((long) bytes[4] << 24)) + | (0xff00000000L & ((long) bytes[3] << 32)) + | (0xff0000000000L & ((long) bytes[2] << 40)) + | (0xff000000000000L & ((long) bytes[1] << 48)) + | (0xff00000000000000L & ((long) bytes[0] << 56)); + } + } + + /** + * 返回由字节数组中的指定的八个字节转换来的 64 位有符号整数 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由八个字节构成的 64 位有符号整数 + */ + public static long toLong(byte[] bytes, int startIndex) { + return toLong(copyFrom(bytes, startIndex, 8)); + } + + /** + * 返回由字节数组转换来的单精度浮点数 + * @param bytes 字节数组 + * @return 由四个字节构成的单精度浮点数 + */ + public static float toFloat(byte[] bytes) { + return Float.intBitsToFloat(toInt(bytes)); + } + + /** + * 返回由字节数组中的指定的四个字节转换来的单精度浮点数 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由四个字节构成的单精度浮点数 + */ + public static float toFloat(byte[] bytes, int startIndex) { + return Float.intBitsToFloat(toInt(copyFrom(bytes, startIndex, 4))); + } + + /** + * 返回由字节数组转换来的双精度浮点数 + * @param bytes 字节数组 + * @return 由八个字节构成的双精度浮点数 + */ + public static double toDouble(byte[] bytes) { + return Double.longBitsToDouble(toLong(bytes)); + } + + /** + * 返回由字节数组中的指定的八个字节转换来的双精度浮点数 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由八个字节构成的双精度浮点数 + */ + public static double toDouble(byte[] bytes, int startIndex) { + return Double.longBitsToDouble(toLong(copyFrom(bytes, startIndex, 8))); + } + + /** + * 返回由字节数组转换来的字符串 + * @param bytes 字节数组 + * @return 字符串 + */ + public static String toString(byte[] bytes) { + return new String(bytes, Charset.forName("UTF-8")); + } + + /** + * 返回由字节数组转换来的字符串 + * @param bytes 字节数组 + * @param charsetName 字符集编码 + * @return 字符串 + */ + public static String toString(byte[] bytes, String charsetName) { + return new String(bytes, Charset.forName(charsetName)); + } + + /** + * 以字符串表示形式返回字节数组的内容 + * @param bytes 字节数组 + * @return 字符串形式的 bytes + */ + public static String toHexString(byte[] bytes) { + if (bytes == null) + return "null"; + int iMax = bytes.length - 1; + if (iMax == -1) + return "[]"; + StringBuilder b = new StringBuilder(); + b.append('['); + for (int i = 0; ; i++) { + b.append(String.format("%02x", bytes[i] & 0xFF)); + if (i == iMax) + return b.append(']').toString(); + b.append(", "); + } + } + + + // -------------------------------------------------------------------------------------------- + + + /** + * 数组拷贝。 + * @param src 字节数组。 + * @param off 起始下标。 + * @param len 拷贝长度。 + * @return 指定长度的字节数组。 + */ + public static byte[] copyFrom(byte[] src, int off, int len) { + // return Arrays.copyOfRange(src, off, off + len); + byte[] bits = new byte[len]; + for (int i = off, j = 0; i < src.length && j < len; i++, j++) { + bits[j] = src[i]; + } + return bits; + } + + /** + * 判断 CPU Endian 是否为 Little + * @return 判断结果 + */ + private static boolean isLittleEndian() { + return ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN; + } +} + diff --git a/modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/DTUServer.java b/modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/DTUServer.java new file mode 100644 index 00000000..54b17160 --- /dev/null +++ b/modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/DTUServer.java @@ -0,0 +1,48 @@ +package com.sarnath.modbusserver.dtuutils; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.logging.LogLevel; +import io.netty.handler.logging.LoggingHandler; + +public class DTUServer { + + static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); + public static void Start() + { + //主工作线程组,设置为1个线程 + EventLoopGroup bossGroup = new NioEventLoopGroup(1); + //工作线程组,默认为内核数*2的线程数 + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .option(ChannelOption.SO_BACKLOG, 100) + .childHandler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + p.addLast(new LoggingHandler(LogLevel.INFO)); + p.addLast(new DTUServerHandler()); + } + }); + + + // Start the server. + ChannelFuture f = b.bind(PORT).sync(); + // Wait until the server socket is closed. + f.channel().closeFuture().sync(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + // Shut down all event loops to terminate all threads. + bossGroup.shutdownGracefully(); + workerGroup.shutdownGracefully(); + } + } + +} diff --git a/modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/DTUServerHandler.java b/modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/DTUServerHandler.java new file mode 100644 index 00000000..6735424e --- /dev/null +++ b/modbus-server/src/main/java/com/sarnath/modbusserver/dtuutils/DTUServerHandler.java @@ -0,0 +1,137 @@ +package com.sarnath.modbusserver.dtuutils; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.net.InetSocketAddress; + +public class DTUServerHandler extends ChannelInboundHandlerAdapter { + + private static final Logger LOG = LoggerFactory.getLogger(DTUServerHandler.class); + + private byte[] cBuf = new byte[0]; + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + InetSocketAddress ipSocket = (InetSocketAddress )ctx.channel().remoteAddress(); + String addr = ipSocket.getAddress().getHostAddress(); + int port = ipSocket.getPort(); + LOG.info("通道读取,对方位于" + addr + ":" + port); + ByteBuf buffer = (ByteBuf)msg; + if (buffer != null) + { + //string msg = BitConverter.ToString(buffer.Array); + //LogUtil.Info(msg); + // 读取长度 + int len = buffer.readableBytes(); + byte[] curBuf = new byte[len]; + buffer.readBytes(curBuf,0,len); + //System.arraycopy(buffer.array(), buffer.arrayOffset(), curBuf, 0, len); + String tempMsg = BitConverter.toHexString(curBuf); + LOG.info("xxxxxxxxx:"+tempMsg); + // + Unpacking(curBuf); + } + } + + /// + /// 递归处理当前包 + /// + /// + private void Unpacking(byte[] curBuf) + { + // 读取长度 + int len = curBuf.length; + // 定义拼接数据包 + byte[] revBuf = new byte[len + cBuf.length]; + // 拼接 缓存数据包 + System.arraycopy(cBuf, 0, revBuf, 0, cBuf.length); + // 拼接 新接收数据包 + System.arraycopy(curBuf, 0, revBuf, cBuf.length, len); + // 使用完重置缓存包 + cBuf = new byte[0]; + // 包长判断 + if (len >= 4) + { + String tempMsg = BitConverter.toHexString(revBuf); + LOG.info("xxxxxxxxx:"+tempMsg); + + String tempMsg2 = BitConverter.toHexString(BitConverter.copyFrom(revBuf, 2, 2)); + LOG.info("xxxxxxxxx2:"+tempMsg2); + LOG.info("xxxxxxxxx2:"+BitConverter.toHexString(BitConverter.getBytes((short) 6))); + //2 3 位为整包长度 + short packageLen = BitConverter.toShort(BitConverter.copyFrom(revBuf, 2, 2)); + LOG.info("packageLen:"+packageLen); + if (packageLen==0) + { + return; + } + if (packageLen > revBuf.length) + { + // 缓存断包 等待下一个数据包 + LOG.info("缓存断包!"); + cBuf = revBuf; + } + else + { + // 根据长度 拆包 + byte[] comBuf = new byte[packageLen]; + System.arraycopy(revBuf, 0, comBuf, 0, packageLen); + // 业务处理 + DoSomeThing(comBuf); + //// 重置缓存包 + //cBuf = new byte[0]; + int remLen = revBuf.length - packageLen; + if (remLen>0) + { + LOG.info("粘包处理!"); + // 重置当前处理包 + curBuf = new byte[remLen]; + System.arraycopy(revBuf, packageLen, curBuf, 0, remLen); + // 递归处理剩余数据包 + Unpacking(curBuf); + } + } + } + else + { + // 缓存断包 等待下一个数据包 + LOG.info("缓存断包!"); + cBuf = revBuf; + } + } + @Override + public void channelReadComplete(ChannelHandlerContext ctx) { + ctx.flush(); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + // Close the connection when an exception is raised. + cause.printStackTrace(); + ctx.close(); + } + + private void DoSomeThing(byte[] comBuf) + { + String msg = BitConverter.toHexString(comBuf); + LOG.info("DoSomeThing:"+msg); + + //int dataLen = BitConverter.ToInt16(comBuf, 2) - 14; + //byte[] DataByte = new byte[dataLen]; + //Array.ConstrainedCopy(comBuf, 14, DataByte, 0, dataLen); + + //// 0 1 头 + //// 2 3 长度 + //// 4 5 厂站号 + //int stationId = BitConverter.ToInt16(comBuf, 4); + //// 6 7 通道号 + //int channelId = BitConverter.ToInt16(comBuf, 6); + //int startAddress = BitConverter.ToInt16(comBuf, 11); + //int type = Convert.ToInt16(comBuf[9]); + //LogUtil.Info("场站号:" + stationId.ToString() + ", 通道号:" + channelId.ToString() + ", 起始地址:" + startAddress+",type:"+ type); + //LogUtil.Info(stationId+":"+string.Join("-", GetRaw(DataByte))); + } +} diff --git a/modbus-server/src/main/resources/banner.txt b/modbus-server/src/main/resources/banner.txt new file mode 100644 index 00000000..d8ac9257 --- /dev/null +++ b/modbus-server/src/main/resources/banner.txt @@ -0,0 +1,8 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} + _____ .______. _________ + / \ ____ __| _/\_ |__ __ __ ______ / _____/ ______________ __ ___________ + / \ / \ / _ \ / __ | | __ \| | \/ ___/ ______ \_____ \_/ __ \_ __ \ \/ // __ \_ __ \ +/ Y ( <_> ) /_/ | | \_\ \ | /\___ \ /_____/ / \ ___/| | \/\ /\ ___/| | \/ +\____|__ /\____/\____ | |___ /____//____ > /_______ /\___ >__| \_/ \___ >__| + \/ \/ \/ \/ \/ \/ \/ diff --git a/modbus-server/src/main/resources/bootstrap.yml b/modbus-server/src/main/resources/bootstrap.yml new file mode 100644 index 00000000..9f339a22 --- /dev/null +++ b/modbus-server/src/main/resources/bootstrap.yml @@ -0,0 +1,24 @@ +# Tomcat +server: + port: 8710 + +# Spring +spring: + application: + # 应用名称 + name: modbus-server + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/modbus-server/src/main/resources/logback.xml b/modbus-server/src/main/resources/logback.xml new file mode 100644 index 00000000..351b5e57 --- /dev/null +++ b/modbus-server/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + :ss} %-5level ${springAppName:-} %thread %logger %msg%n"/> + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index ac7bbabe..b0eeaecc 100644 --- a/pom.xml +++ b/pom.xml @@ -71,21 +71,21 @@ pom import - + de.codecentric spring-boot-admin-starter-client ${spring-boot-admin.version} - + org.mybatis.spring.boot mybatis-spring-boot-starter ${spring-boot.mybatis} - + io.swagger @@ -146,7 +146,7 @@ fastjson ${fastjson.version} - + org.apache.commons @@ -160,49 +160,49 @@ ruoyi-common-core ${ruoyi.version} - + com.ruoyi ruoyi-common-swagger ${ruoyi.version} - + com.ruoyi ruoyi-common-security ${ruoyi.version} - + com.ruoyi ruoyi-common-datascope ${ruoyi.version} - + com.ruoyi ruoyi-common-log ${ruoyi.version} - + com.ruoyi ruoyi-common-redis ${ruoyi.version} - + com.ruoyi ruoyi-api-system ${ruoyi.version} - + @@ -213,11 +213,12 @@ ruoyi-modules ruoyi-api ruoyi-common + modbus-server pom - + @@ -234,4 +235,4 @@ - \ No newline at end of file + diff --git a/ruoyi-api/ruoyi-api-system/pom.xml b/ruoyi-api/ruoyi-api-system/pom.xml index 6f9997c9..0b1973d3 100644 --- a/ruoyi-api/ruoyi-api-system/pom.xml +++ b/ruoyi-api/ruoyi-api-system/pom.xml @@ -8,7 +8,7 @@ 2.0.0 4.0.0 - + ruoyi-api-system @@ -16,13 +16,13 @@ - + com.ruoyi ruoyi-common-core - + - \ No newline at end of file + diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/BitConverter.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/BitConverter.java new file mode 100644 index 00000000..5b4397b0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/BitConverter.java @@ -0,0 +1,380 @@ +package com.ruoyi.common.core.utils; + +import java.nio.ByteOrder; +import java.nio.charset.Charset; + +/** + * 数字转字节数组工具类 + */ +public class BitConverter { + + /** + * 以字节数组的形式返回指定的布尔值 + * @param data 一个布尔值 + * @return 长度为 1 的字节数组 + */ + public static byte[] getBytes(boolean data) { + byte[] bytes = new byte[1]; + bytes[0] = (byte) (data ? 1 : 0); + return bytes; + } + + /** + * 以字节数组的形式返回指定的 16 位有符号整数值 + * @param data 要转换的数字 + * @return 长度为 2 的字节数组 + */ + public static byte[] getBytes(short data) { + byte[] bytes = new byte[2]; + if (isLittleEndian()) { + bytes[0] = (byte) (data & 0xff); + bytes[1] = (byte) ((data & 0xff00) >> 8); + } else { + bytes[1] = (byte) (data & 0xff); + bytes[0] = (byte) ((data & 0xff00) >> 8); + } + return bytes; + } + + /** + * 以字节数组的形式返回指定的 Unicode 字符值 + * @param data 要转换的字符 + * @return 长度为 2 的字节数组 + */ + public static byte[] getBytes(char data) { + byte[] bytes = new byte[2]; + if (isLittleEndian()) { + bytes[0] = (byte) (data); + bytes[1] = (byte) (data >> 8); + } else { + bytes[1] = (byte) (data); + bytes[0] = (byte) (data >> 8); + } + return bytes; + } + + /** + * 以字节数组的形式返回指定的 32 位有符号整数值 + * @param data 要转换的数字 + * @return 长度为 4 的字节数组 + */ + public static byte[] getBytes(int data) { + byte[] bytes = new byte[4]; + if (isLittleEndian()) { + bytes[0] = (byte) (data & 0xff); + bytes[1] = (byte) ((data & 0xff00) >> 8); + bytes[2] = (byte) ((data & 0xff0000) >> 16); + bytes[3] = (byte) ((data & 0xff000000) >> 24); + } else { + bytes[3] = (byte) (data & 0xff); + bytes[2] = (byte) ((data & 0xff00) >> 8); + bytes[1] = (byte) ((data & 0xff0000) >> 16); + bytes[0] = (byte) ((data & 0xff000000) >> 24); + } + return bytes; + } + + /** + * 以字节数组的形式返回指定的 64 位有符号整数值 + * @param data 要转换的数字 + * @return 长度为 8 的字节数组 + */ + public static byte[] getBytes(long data) { + byte[] bytes = new byte[8]; + if (isLittleEndian()) { + bytes[0] = (byte) (data & 0xff); + bytes[1] = (byte) ((data >> 8) & 0xff); + bytes[2] = (byte) ((data >> 16) & 0xff); + bytes[3] = (byte) ((data >> 24) & 0xff); + bytes[4] = (byte) ((data >> 32) & 0xff); + bytes[5] = (byte) ((data >> 40) & 0xff); + bytes[6] = (byte) ((data >> 48) & 0xff); + bytes[7] = (byte) ((data >> 56) & 0xff); + } else { + bytes[7] = (byte) (data & 0xff); + bytes[6] = (byte) ((data >> 8) & 0xff); + bytes[5] = (byte) ((data >> 16) & 0xff); + bytes[4] = (byte) ((data >> 24) & 0xff); + bytes[3] = (byte) ((data >> 32) & 0xff); + bytes[2] = (byte) ((data >> 40) & 0xff); + bytes[1] = (byte) ((data >> 48) & 0xff); + bytes[0] = (byte) ((data >> 56) & 0xff); + } + return bytes; + } + + /** + * 以字节数组的形式返回指定的单精度浮点值 + * @param data 要转换的数字 + * @return 长度为 4 的字节数组 + */ + public static byte[] getBytes(float data) { + return getBytes(Float.floatToIntBits(data)); + } + + /** + * 以字节数组的形式返回指定的双精度浮点值 + * @param data 要转换的数字 + * @return 长度为 8 的字节数组 + */ + public static byte[] getBytes(double data) { + return getBytes(Double.doubleToLongBits(data)); + } + + /** + * 将指定字符串中的所有字符编码为一个字节序列 + * @param data 包含要编码的字符的字符串 + * @return 一个字节数组,包含对指定的字符集进行编码的结果 + */ + public static byte[] getBytes(String data) { + return data.getBytes(Charset.forName("UTF-8")); + } + + /** + * 将指定字符串中的所有字符编码为一个字节序列 + * @param data 包含要编码的字符的字符串 + * @param charsetName 字符集编码 + * @return 一个字节数组,包含对指定的字符集进行编码的结果 + */ + public static byte[] getBytes(String data, String charsetName) { + return data.getBytes(Charset.forName(charsetName)); + } + + /** + * 返回由字节数组转换来的布尔值 + * @param bytes 字节数组 + * @return 布尔值 + */ + public static boolean toBoolean(byte[] bytes) { + return bytes[0] == 0 ? false : true; + } + + /** + * 返回由字节数组中的指定的一个字节转换来的布尔值 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 布尔值 + */ + public static boolean toBoolean(byte[] bytes, int startIndex) { + return toBoolean(copyFrom(bytes, startIndex, 1)); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + if (isLittleEndian()) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + } else { + return (short) ((0xff & bytes[1]) | (0xff00 & (bytes[0] << 8))); + } + } + + /** + * 返回由字节数组中的指定的两个字节转换来的 16 位有符号整数 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes, int startIndex) { + return toShort(copyFrom(bytes, startIndex, 2)); + } + + /** + * 返回由字节数组转换来的 Unicode 字符 + * @param bytes 字节数组 + * @return 由两个字节构成的字符 + */ + public static char toChar(byte[] bytes) { + if (isLittleEndian()) { + return (char) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + } else { + return (char) ((0xff & bytes[1]) | (0xff00 & (bytes[0] << 8))); + } + } + + /** + * 返回由字节数组中的指定的两个字节转换来的 Unicode 字符 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由两个字节构成的字符 + */ + public static char toChar(byte[] bytes, int startIndex) { + return toChar(copyFrom(bytes, startIndex, 2)); + } + + /** + * 返回由字节数组转换来的 32 位有符号整数 + * @param bytes 字节数组 + * @return 由四个字节构成的 32 位有符号整数 + */ + public static int toInt(byte[] bytes) { + if (isLittleEndian()) { + return (0xff & bytes[0]) + | (0xff00 & (bytes[1] << 8)) + | (0xff0000 & (bytes[2] << 16)) + | (0xff000000 & (bytes[3] << 24)); + } else { + return (0xff & bytes[3]) + | (0xff00 & (bytes[2] << 8)) + | (0xff0000 & (bytes[1] << 16)) + | (0xff000000 & (bytes[0] << 24)); + } + } + + /** + * 返回由字节数组中的指定的四个字节转换来的 32 位有符号整数 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由四个字节构成的 32 位有符号整数 + */ + public static int toInt(byte[] bytes, int startIndex) { + return toInt(copyFrom(bytes, startIndex, 4)); + } + + /** + * 返回由字节数组转换来的 64 位有符号整数 + * @param bytes 字节数组 + * @return 由八个字节构成的 64 位有符号整数 + */ + public static long toLong(byte[] bytes) { + if (isLittleEndian()) { + return (0xffL & (long) bytes[0]) + | (0xff00L & ((long) bytes[1] << 8)) + | (0xff0000L & ((long) bytes[2] << 16)) + | (0xff000000L & ((long) bytes[3] << 24)) + | (0xff00000000L & ((long) bytes[4] << 32)) + | (0xff0000000000L & ((long) bytes[5] << 40)) + | (0xff000000000000L & ((long) bytes[6] << 48)) + | (0xff00000000000000L & ((long) bytes[7] << 56)); + } else { + return (0xffL & (long) bytes[7]) + | (0xff00L & ((long) bytes[6] << 8)) + | (0xff0000L & ((long) bytes[5] << 16)) + | (0xff000000L & ((long) bytes[4] << 24)) + | (0xff00000000L & ((long) bytes[3] << 32)) + | (0xff0000000000L & ((long) bytes[2] << 40)) + | (0xff000000000000L & ((long) bytes[1] << 48)) + | (0xff00000000000000L & ((long) bytes[0] << 56)); + } + } + + /** + * 返回由字节数组中的指定的八个字节转换来的 64 位有符号整数 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由八个字节构成的 64 位有符号整数 + */ + public static long toLong(byte[] bytes, int startIndex) { + return toLong(copyFrom(bytes, startIndex, 8)); + } + + /** + * 返回由字节数组转换来的单精度浮点数 + * @param bytes 字节数组 + * @return 由四个字节构成的单精度浮点数 + */ + public static float toFloat(byte[] bytes) { + return Float.intBitsToFloat(toInt(bytes)); + } + + /** + * 返回由字节数组中的指定的四个字节转换来的单精度浮点数 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由四个字节构成的单精度浮点数 + */ + public static float toFloat(byte[] bytes, int startIndex) { + return Float.intBitsToFloat(toInt(copyFrom(bytes, startIndex, 4))); + } + + /** + * 返回由字节数组转换来的双精度浮点数 + * @param bytes 字节数组 + * @return 由八个字节构成的双精度浮点数 + */ + public static double toDouble(byte[] bytes) { + return Double.longBitsToDouble(toLong(bytes)); + } + + /** + * 返回由字节数组中的指定的八个字节转换来的双精度浮点数 + * @param bytes 字节数组 + * @param startIndex 起始下标 + * @return 由八个字节构成的双精度浮点数 + */ + public static double toDouble(byte[] bytes, int startIndex) { + return Double.longBitsToDouble(toLong(copyFrom(bytes, startIndex, 8))); + } + + /** + * 返回由字节数组转换来的字符串 + * @param bytes 字节数组 + * @return 字符串 + */ + public static String toString(byte[] bytes) { + return new String(bytes, Charset.forName("UTF-8")); + } + + /** + * 返回由字节数组转换来的字符串 + * @param bytes 字节数组 + * @param charsetName 字符集编码 + * @return 字符串 + */ + public static String toString(byte[] bytes, String charsetName) { + return new String(bytes, Charset.forName(charsetName)); + } + + /** + * 以字符串表示形式返回字节数组的内容 + * @param bytes 字节数组 + * @return 字符串形式的 bytes + */ + public static String toHexString(byte[] bytes) { + if (bytes == null) + return "null"; + int iMax = bytes.length - 1; + if (iMax == -1) + return "[]"; + StringBuilder b = new StringBuilder(); + b.append('['); + for (int i = 0; ; i++) { + b.append(String.format("%02x", bytes[i] & 0xFF)); + if (i == iMax) + return b.append(']').toString(); + b.append(", "); + } + } + + + // -------------------------------------------------------------------------------------------- + + + /** + * 数组拷贝。 + * @param src 字节数组。 + * @param off 起始下标。 + * @param len 拷贝长度。 + * @return 指定长度的字节数组。 + */ + private static byte[] copyFrom(byte[] src, int off, int len) { + // return Arrays.copyOfRange(src, off, off + len); + byte[] bits = new byte[len]; + for (int i = off, j = 0; i < src.length && j < len; i++, j++) { + bits[j] = src[i]; + } + return bits; + } + + /** + * 判断 CPU Endian 是否为 Little + * @return 判断结果 + */ + private static boolean isLittleEndian() { + return ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN; + } +} + diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/RuoYiGatewayApplication.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/RuoYiGatewayApplication.java index d1f6ec14..0533aaf4 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/RuoYiGatewayApplication.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/RuoYiGatewayApplication.java @@ -7,11 +7,11 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * 网关启动程序 - * + * * @author ruoyi */ @EnableDiscoveryClient -@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })// 关闭自动配置功能 public class RuoYiGatewayApplication { public static void main(String[] args) @@ -28,4 +28,4 @@ public class RuoYiGatewayApplication " | | \\ / \\ / \n" + " ''-' `'-' `-..-' "); } -} \ No newline at end of file +} diff --git a/ruoyi-modules/ruoyi-system/pom.xml b/ruoyi-modules/ruoyi-system/pom.xml index bddafc43..d30bf4c3 100644 --- a/ruoyi-modules/ruoyi-system/pom.xml +++ b/ruoyi-modules/ruoyi-system/pom.xml @@ -8,76 +8,76 @@ 2.0.0 4.0.0 - + ruoyi-modules-system ruoyi-modules-system系统模块 - + - + com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery - + com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config - + com.alibaba.cloud spring-cloud-starter-alibaba-sentinel - + org.springframework.boot spring-boot-starter-web - + io.springfox springfox-swagger-ui ${swagger.fox.version} - + mysql mysql-connector-java - + com.ruoyi ruoyi-common-security - + com.ruoyi ruoyi-common-datascope - + com.ruoyi ruoyi-common-log - + com.ruoyi ruoyi-common-swagger - + com.ruoyi @@ -101,5 +101,5 @@ - - \ No newline at end of file + + diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java index a8509575..b412abaa 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.List; import java.util.Set; import javax.servlet.http.HttpServletResponse; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; diff --git a/ruoyi-visual/hystrix-dashboard/pom.xml b/ruoyi-visual/hystrix-dashboard/pom.xml new file mode 100644 index 00000000..0043d868 --- /dev/null +++ b/ruoyi-visual/hystrix-dashboard/pom.xml @@ -0,0 +1,67 @@ + + + + ruoyi-visual + com.ruoyi + 2.0.0 + + 4.0.0 + + hystrix-dashboard + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.netflix.hystrix + hystrix-javanica + RELEASE + + + org.springframework.cloud + spring-cloud-netflix-hystrix-dashboard + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/ruoyi-visual/hystrix-dashboard/src/main/java/com/sarnath/hystrix/dashboard/HystrixDashBoardApplication.java b/ruoyi-visual/hystrix-dashboard/src/main/java/com/sarnath/hystrix/dashboard/HystrixDashBoardApplication.java new file mode 100644 index 00000000..04077552 --- /dev/null +++ b/ruoyi-visual/hystrix-dashboard/src/main/java/com/sarnath/hystrix/dashboard/HystrixDashBoardApplication.java @@ -0,0 +1,22 @@ +package com.sarnath.hystrix.dashboard; + +import org.springframework.boot.SpringApplication; +import org.springframework.cloud.client.SpringCloudApplication; +import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; + +@EnableHystrixDashboard +@SpringCloudApplication +public class HystrixDashBoardApplication { + public static void main(String[] args) + { + SpringApplication.run(HystrixDashBoardApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ hystrix-dashboard服务模块启动成功 ლ(´ڡ`ლ)゙ \n" + + "____.___._________ \n" + + "\\__ | |\\_ ___ \\ \n" + + " / | |/ \\ \\/ \n" + + " \\____ |\\ \\____\n" + + " / ______| \\______ /\n" + + " \\/ \\/ "); + + } +} diff --git a/ruoyi-visual/hystrix-dashboard/src/main/resources/banner.txt b/ruoyi-visual/hystrix-dashboard/src/main/resources/banner.txt new file mode 100644 index 00000000..71027b75 --- /dev/null +++ b/ruoyi-visual/hystrix-dashboard/src/main/resources/banner.txt @@ -0,0 +1,8 @@ +Spring Boot Version: ${spring-boot.version} +Spring Application Name: ${spring.application.name} +.__ __ .__ .___ .__ ___. .___ +| |__ ___.__. _______/ |________|__|__ ___ __| _/____ _____| |__\_ |__ _________ _______ __| _/ +| | < | |/ ___/\ __\_ __ \ \ \/ / ______ / __ |\__ \ / ___/ | \| __ \ / _ \__ \\_ __ \/ __ | +| Y \___ |\___ \ | | | | \/ |> < /_____/ / /_/ | / __ \_\___ \| Y \ \_\ ( <_> ) __ \| | \/ /_/ | +|___| / ____/____ > |__| |__| |__/__/\_ \ \____ |(____ /____ >___| /___ /\____(____ /__| \____ | + \/\/ \/ \/ \/ \/ \/ \/ \/ \/ \/ diff --git a/ruoyi-visual/hystrix-dashboard/src/main/resources/bootstrap.yml b/ruoyi-visual/hystrix-dashboard/src/main/resources/bootstrap.yml new file mode 100644 index 00000000..11cda9a1 --- /dev/null +++ b/ruoyi-visual/hystrix-dashboard/src/main/resources/bootstrap.yml @@ -0,0 +1,24 @@ +# Tomcat +server: + port: 8100 + +# Spring +spring: + application: + # 应用名称 + name: hystrix-dashboard + profiles: + # 环境配置 + active: dev + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: 127.0.0.1:8848 + config: + # 配置中心地址 + server-addr: 127.0.0.1:8848 + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} diff --git a/ruoyi-visual/pom.xml b/ruoyi-visual/pom.xml index d2838a92..68365f5c 100644 --- a/ruoyi-visual/pom.xml +++ b/ruoyi-visual/pom.xml @@ -10,6 +10,7 @@ ruoyi-monitor + hystrix-dashboard ruoyi-visual