liurunyu
2023-11-27 c475f9ad3290c2593897736144758b54e2b2f407
mwTest-client初步实现
40个文件已添加
2438 ■■■■■ 已修改文件
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/.gitignore 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/pom.xml 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/AdapterImp_HttpClUnit.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/AdapterImp_RmiClUnit.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/AdapterImp_SupportUnit.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/Server.java 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/ServerProperties.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/HttpClUnit.java 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/HttpClUnitAdapter.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/HttpClUnitConfigVo.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/HttpPost.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/MyThreadJob.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/RtuData4HAC_NBhV2_5.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/RtuData4MeterV1_0.java 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/TestBase64.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/UpDataPayloadVo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/UpDataVo.java 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/Code.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/ResConfigVo.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/ResRegisterVo.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/ResStartVo.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiClUnit.java 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiClUnitAdapter.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiClUnitConfigVo.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiClient.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiRequestVo.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiResponseVo.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/MyThreadJob.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/TcpClUnit.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/TcpClUnitAdapter.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/TcpClUnitConfigVo.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/LocalCodecFactory.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/LocalDecoder.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/LocalEncoder.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/MinaConnect.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/MinaConnectPool.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/MinaHandler.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/resources/Config.xml 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/resources/application.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/resources/log4j2.yml 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/.gitignore
New file
@@ -0,0 +1,34 @@
HELP.md
target/
/pipIrr-mwTest-client.iml
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/pom.xml
New file
@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>pipIrr-mw</artifactId>
        <groupId>com.dy</groupId>
        <version>1.0.0</version>
    </parent>
    <packaging>jar</packaging>
    <artifactId>pipIrr-mwTest-client</artifactId>
    <version>1.0.0</version>
    <name>pipIrr-mwTest-client</name>
    <description>模拟RTU测试端</description>
    <dependencies>
        <!-- apache mina -->
        <dependency>
            <groupId>org.apache.mina</groupId>
            <artifactId>mina-core</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.7</version>
        </dependency>
        <!-- 测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <!-- 该插件不会将项目中引入的依赖打进最终的 Jar 文件 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <!-- 生成的jar中,不要包含pom.xml和pom.properties这两个文件 -->
                        <addMavenDescriptor>false</addMavenDescriptor>
                        <!-- 这部分可有可无,加上的话则直接生成可运行jar包 -->
                        <manifest>
                            <mainClass>com.dy.testClient.Server</mainClass>
                            <useUniqueVersions>false</useUniqueVersions>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                        </manifest>
                        <!-- manifestEntries的作用是指定本地(自己下载的lib下的)jar包添加到MANIFEST.MF文件中去
                        <manifestEntries>
                            <Class-Path>.lib/alipay-sdk.java.jar</Class-Path>
                        </manifestEntries>
                        -->
                    </archive>
                    <!-- 排除某个文件
                    <excludes>
                        <exclude>com/dy/App.class</exclude>
                    </excludes>
                    -->
                    <!-- 可执行jar进行命名。这样会打包成两个jar包,不会对普通jar重新命名。
                    <classifier>exec</classifier>
                     -->
                </configuration>
            </plugin>
            <plugin>
                <!-- 当项目中依赖比较多时,我们可以借助 maven-dependency-plugin 插件自动帮我们下载依赖的 Jar 文件,推荐将该插件绑定到package生命周期上 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <!-- 绑定生命周期 -->
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <!-- 设置依赖的存放路径 -->
                        <configuration>
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <!-- 设置java编译版本,运行环境版本 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <!-- source: 源代码编译版本;target: 目标平台编译版本;encoding: 字符集编码。 -->
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${encoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <!-- 解决资源文件的编码问题 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>${encoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <!-- maven里执行测试用例的插件 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/AdapterImp_HttpClUnit.java
New file
@@ -0,0 +1,19 @@
package com.dy.testClient;
import com.dy.testClient.tcpClient.TcpClUnitAdapter;
import com.dy.testClient.tcpClient.TcpClUnitConfigVo;
public class AdapterImp_TcpClUnit implements TcpClUnitAdapter {
    private TcpClUnitConfigVo configVo ;
    public TcpClUnitConfigVo getConfig() {
        return configVo;
    }
    public void setConfig(TcpClUnitConfigVo configVo){
        this.configVo = configVo ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/AdapterImp_RmiClUnit.java
New file
@@ -0,0 +1,19 @@
package com.dy.testClient;
import com.dy.testClient.rmiClient.RmiClUnitAdapter;
import com.dy.testClient.rmiClient.RmiClUnitConfigVo;
public class AdapterImp_RmiClUnit implements RmiClUnitAdapter {
    private RmiClUnitConfigVo configVo ;
    public RmiClUnitConfigVo getConfig() {
        return configVo;
    }
    public void setConfig(RmiClUnitConfigVo configVo){
        this.configVo = configVo ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/AdapterImp_SupportUnit.java
New file
@@ -0,0 +1,20 @@
package com.dy.testClient;
import com.dy.common.mw.support.SupportUnitAdapter;
import com.dy.common.mw.support.SupportUnitConfigVo;
public class AdapterImp_SupportUnit implements SupportUnitAdapter {
    private SupportUnitConfigVo configVo = null ;
    @Override
    public SupportUnitConfigVo getConfig() {
        return this.configVo;
    }
    public void setConfig(SupportUnitConfigVo configVo) {
        this.configVo = configVo;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/Server.java
New file
@@ -0,0 +1,134 @@
package com.dy.testClient;
import java.util.ArrayList;
import java.util.List;
import com.dy.testClient.tcpClient.TcpClUnit;
import com.dy.testClient.tcpClient.TcpClUnitConfigVo;
import org.jdom2.Document;
import com.dy.testClient.rmiClient.RmiClUnit;
import com.dy.testClient.rmiClient.RmiClUnitConfigVo;
import com.dy.common.mw.UnitInterface;
import com.dy.common.mw.support.SupportUnit;
import com.dy.common.mw.support.SupportUnitConfigVo;
import com.dy.common.util.ConfigXml;
public class Server {
    private ConfigXml conf = null ;
    private Document doc = null ;
    private boolean showStartInfo = false ;
    private final List<UnitInterface> units = new ArrayList<UnitInterface>() ;
    /**
     * @param args
     */
    public static void main(String[] args) {
        Server sv = new Server();
        Long start = System.currentTimeMillis() ;
        try {
            sv.conf = new ConfigXml() ;
            sv.doc = sv.conf.createDom(sv.getClass(), "/config.xml") ;
            ////////////////
            //服务 配置
            sv.showStartInfo = sv.conf.getSetAttrBoolean(sv.doc, "config.server", "showStartInfo", null, null) ;
            sv.startUnits() ;
            String svName = null ;
            try{
                svName = sv.conf.getSetAttrTxt(sv.doc, "config.server", "name", null, false, null) ;
            }catch(Exception e){
                svName = "" ;
            }
            System.out.println("") ;
            System.out.println("OOOOOOOOOO           OOOOOOOO       OOOOOOOO") ;
            System.out.println("@@@@@@@@@@@@@@@@#O    $@@@@@@@@&    @@@@@@@@#") ;
            System.out.println("@@@@@@@@@@@@@@@@@@@#    @@@@@@@@# $@@@@@@@@&") ;
            System.out.println("@@@@@@@@@@@@@@@@@@@@@#   #@@@@@@@@@@@@@@@@O") ;
            System.out.println("@@@@@@@@@@@@@@@@@@@@@@@   &@@@@@@@@@@@@@@") ;
            System.out.println("@@@@@@$      $@@@@@@@@@&   O@@@@@@@@@@@#") ;
            System.out.println("@@@@@@$        @@@@@@@@@     @@@@@@@@@&  " + svName + "tcpTestClient " ) ;
            System.out.println("@@@@@@$        @@@@@@@@@     &@@@@@@@@") ;
            System.out.println("@@@@@@$       O@@@@@@@@@     &@@@@@@@@") ;
            System.out.println("@@@@@@$      #@@@@@@@@@$     &@@@@@@@@" ) ;
            System.out.println("@@@@@@@@@@@@@@@@@@@@@@#      &@@@@@@@@   Runing in standalone mode" ) ;
            System.out.println("@@@@@@@@@@@@@@@@@@@@@&       &@@@@@@@@   Startup in " + (System.currentTimeMillis() - start) + " MS" ) ;
            System.out.println("@@@@@@@@@@@@@@@@@@@#         &@@@@@@@@") ;
            System.out.println("@@@@@@@@@@@@@@@@#O           &@@@@@@@@") ;
            System.out.println("") ;
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    private void startUnits(){
        try {
            ////////////////////////////////////////////////////////
            //支持模块: springHibernate和 线程池
            SupportUnitConfigVo supVo = new SupportUnitConfigVo() ;
            //短工作时长线程池,线程负责用时较短的工作任务
            supVo.short_maxThread = conf.getSetAttrPlusInt(doc, "config.support", "short_maxThread", null, 1, 1000, null) ;//池中最大线程数为所有CPU核数+1
            supVo.short_minThread = conf.getSetAttrPlusInt(doc, "config.support", "short_minThread", null, 1, 5, null) ;//池中最小线程数
            supVo.short_freeTimeout = conf.getSetAttrPlusInt(doc, "config.support", "short_freeTimeout", null, 1, 90, null) * 1000 ;//线程数空闲时长,若池中线程数量大于minThread,且有的线程空闲时长超过freeTimeout,则清除该线程,为了不清除,把minThread与maxThread设置相等
            supVo.short_busyTimeout = conf.getSetAttrPlusInt(doc, "config.support", "short_busyTimeout", null, 1, 10, null) * 1000 ;//线程不间断工作时长(单位为秒)超时限,认为线程已经了崩溃,将强制清除,短工作时长设置为5秒
            //长工作时长线程池,线程负责用时较长的工作任务
            supVo.long_maxThread = conf.getSetAttrInt(doc, "config.support", "long_maxThread", null, -1, 1000, null)  ;//池中最大线程数,若为-1,不受限制
            if(supVo.long_maxThread < 0){
                supVo.long_maxThread = -1 ;
            }
            supVo.long_minThread = conf.getSetAttrPlusInt(doc, "config.support", "long_minThread", null, 0, 5, null) ;//池中最小线程数
            supVo.long_freeTimeout = conf.getSetAttrPlusInt(doc, "config.support", "long_freeTimeout", null, 1, 90, null) * 1000 ;//线程数空闲时长,若池中线程数量大于minThread,且有的线程空闲时长超过freeTimeout,则清除该线程
            supVo.long_busyTimeout = conf.getSetAttrInt(doc, "config.support", "long_busyTimeout", null, -1, 10, null) ;//线程不间断工作时长(单位为秒)超时限,若为-1,不受限制
            if(supVo.long_busyTimeout < 0){
                supVo.long_busyTimeout = -1 ;
            }
            supVo.showStartInfo = showStartInfo ;
            AdapterImp_SupportUnit supAdap = new AdapterImp_SupportUnit() ;
            supAdap.setConfig(supVo);
            SupportUnit supUnit = SupportUnit.getInstance() ;
            supUnit.setAdapter(supAdap);
            supUnit.start(obj -> {
            });
            units.add(supUnit) ;
            // ///////////////
            // rmi 模块
            RmiClUnitConfigVo rmiClVo = new RmiClUnitConfigVo();
            rmiClVo.svUrl = conf.getSetAttrTxt(doc, "config.rmiCl", "rmiSvUrl", null, false, null) ;
            rmiClVo.svContext = conf.getSetAttrTxt(doc, "config.rmiCl", "rmiSvContext", null, false, null) ;
            rmiClVo.svPort = conf.getSetAttrPlusInt(doc, "config.rmiCl", "rmiSvPort", null, 0, 65535, null) ;
            AdapterImp_RmiClUnit rmiClAdap = new AdapterImp_RmiClUnit();
            rmiClAdap.setConfig(rmiClVo);
            RmiClUnit rmiClUnit = RmiClUnit.getInstance();
            rmiClUnit.setAdapter(rmiClAdap);
            rmiClUnit.start(obj -> {
            });
            units.add(rmiClUnit) ;
            // ///////////////
            // Tcp Client 模块
            TcpClUnitConfigVo tcpClVo = new TcpClUnitConfigVo();
            tcpClVo.enable = conf.getSetAttrBoolean(doc, "config.tcpCl", "enable", null, null) ;
            tcpClVo.heartbeatTimes = conf.getSetAttrPlusInt(doc, "config.tcpCl", "heartbeatTimes", null, 1, 10, null) ;//连续配置次数心跳后发送一次数据
            tcpClVo.sendInterval = conf.getSetAttrPlusInt(doc, "config.tcpCl", "sendInterval", null, 1, 60, null) ;//发送心跳或数据的时间间隔
            if(tcpClVo.enable){
                AdapterImp_TcpClUnit httpClAdap = new AdapterImp_TcpClUnit();
                httpClAdap.setConfig(tcpClVo);
                TcpClUnit httpClUnit = TcpClUnit.getInstance();
                httpClUnit.setAdapter(httpClAdap);
                httpClUnit.start(obj -> {
                });
                units.add(httpClUnit) ;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/ServerProperties.java
New file
@@ -0,0 +1,18 @@
package com.dy.testClient;
public class ServerProperties {
    //RTU开始地址
    public static Long rtuAddrStart = 0L ;
    //RTU截止地址
    public static Long rtuAddrEnd = 0L ;
    //服务端IP
    public static String serverIp = "" ;
    //服务端上下文
    public static Integer serverPort = 0 ;
    //发送数据次数
    public static Integer sendTimes = 0 ;
    //mwTestServer控制是否启动
    public static boolean startWork = false ;
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/HttpClUnit.java
New file
@@ -0,0 +1,112 @@
package com.dy.testClient.httpCl;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.dy.testClient.rmiClient.RmiClUnit;
import com.dy.testClient.ServerProperties;
import com.dy.common.threadPool.ThreadPool;
import com.dy.common.threadPool.TreadPoolFactory;
import com.dy.common.mw.UnitAdapterInterface;
import com.dy.common.mw.UnitInterface;
import com.dy.common.mw.UnitStartedCallbackInterface;
public class HttpClUnit implements UnitInterface {
    private static Logger log = LogManager.getLogger(HttpClUnit.class) ;
    private static HttpClUnit instance = new HttpClUnit() ;
    public static HttpClUnitAdapter adapter ;
    public static HttpClUnitConfigVo confVo ;
    private static ThreadPool.Pool pool ;
    private static Integer totalRunedClientCount = 0;
    private static Integer totalOverClientCount = 0;
    private static Long startTime = 0L ;
    private HttpClUnit(){} ;
    public static HttpClUnit getInstance(){
        return instance ;
    }
    @Override
    public void setAdapter(UnitAdapterInterface adapter) throws Exception {
        if(adapter == null){
            throw new Exception("Http Client模块适配器对象不能为空!") ;
        }
        HttpClUnit.adapter = (HttpClUnitAdapter)adapter ;
        HttpClUnit.confVo = HttpClUnit.adapter.getConfig() ;
        if(HttpClUnit.confVo == null){
            throw new Exception("Http Client模块配置对象不能为空!") ;
        }
    }
    @Override
    public void start(UnitStartedCallbackInterface callback) throws Exception {
        pool = TreadPoolFactory.getThreadPoolLong() ;
        System.out.println("Http Client模块成功启动");
        this.doStart();
        callback.call(null) ;
    }
    @Override
    public void stop(UnitStartedCallbackInterface callback) throws Exception {
        callback.call(null);
    }
    private void doStart(){
        new Thread(new Runnable(){
            @Override
            public void run() {
                try {
                    while(true){
                        if(!ServerProperties.startWork){
                            Thread.sleep(100L);
                        }else{
                            startTime = System.currentTimeMillis() ;
                            for(Long i = ServerProperties.rtuAddrStart ; i <= ServerProperties.rtuAddrEnd; i++){
                                totalRunedClientCount++ ;
                                startClient(i) ;
                            }
                            while(true){
                                if(totalOverClientCount.longValue() >= totalRunedClientCount.longValue()){
                                    Long seconds = (System.currentTimeMillis() - startTime)/1000 ;
                                    RmiClUnit.getInstance().reportHadReportOver(seconds) ;
                                    System.out.println("共用时" + seconds + "秒");
                                    break ;
                                }else{
                                    Thread.sleep(100L);
                                }
                            }
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    private void startClient(Long imei){
        try {
            pool.putJob(new MyThreadJob("" + imei));
        } catch (Exception e) {
            log.error("HttpClUnit.startClient() ", e);
        }
    }
    public static synchronized void clientOver(){
        totalOverClientCount++;
        if(totalOverClientCount % 100 == 0){
            RmiClUnit.getInstance().reportHadReportCount(totalOverClientCount);
            System.out.println("已经发送" + totalOverClientCount + "条数据");
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/HttpClUnitAdapter.java
New file
@@ -0,0 +1,9 @@
package com.dy.testClient.httpCl;
import com.dy.common.mw.UnitAdapterInterface;
public interface HttpClUnitAdapter extends UnitAdapterInterface {
    public HttpClUnitConfigVo getConfig() ;
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/HttpClUnitConfigVo.java
New file
@@ -0,0 +1,5 @@
package com.dy.testClient.httpCl;
public class HttpClUnitConfigVo {
    public boolean enable ;
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/HttpPost.java
New file
@@ -0,0 +1,11 @@
package com.dy.testClient.httpCl;
import com.dy.testClient.ServerProperties;
import com.dy.common.util.HttpUtils;
public class HttpPost {
    public static synchronized void post(byte[] bytes) throws Exception{
        //HttpUtils.doPost(ServerProperties.serverUrl, ServerProperties.serverContext, null, null, bytes) ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/MyThreadJob.java
New file
@@ -0,0 +1,76 @@
package com.dy.testClient.httpCl;
import java.util.Base64;
import com.dy.common.threadPool.ThreadPool;
public class MyThreadJob implements ThreadPool.Job {
    public String imei ;
    public MyThreadJob(){
    }
    public MyThreadJob(String imei){
        this.imei = imei ;
    }
    @Override
    public void execute() throws Exception {
        testMeterV1_0() ;
        //testHAC_NBhV2_5() ;
    }
    private void testMeterV1_0(){
        try{
            RtuData4MeterV1_0 rd = new RtuData4MeterV1_0() ;
            byte[] bs = rd.create(imei) ;
            bs = Base64.getEncoder().encode(bs) ;
            UpDataPayloadVo payloadVo = new UpDataPayloadVo() ;
            payloadVo.APPdata = new String(bs, "UTF-8") ;
            UpDataVo vo = new UpDataVo(imei, "8086" + imei ) ;
            vo.payload = payloadVo ;
            String json = vo.toJson() ;
            byte[] bytes = json.getBytes() ;
            HttpPost.post(bytes);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            HttpClUnit.clientOver() ;
        }
    }
    @SuppressWarnings("unused")
    private void testHAC_NBhV2_5(){
        try{
            RtuData4HAC_NBhV2_5 rd = new RtuData4HAC_NBhV2_5() ;
            byte[] bs = rd.create(imei) ;
            bs = Base64.getEncoder().encode(bs) ;
            UpDataPayloadVo payloadVo = new UpDataPayloadVo() ;
            payloadVo.APPdata = new String(bs, "UTF-8") ;
            UpDataVo vo = new UpDataVo(imei, "8086" + imei ) ;
            vo.payload = payloadVo ;
            String json = vo.toJson() ;
            byte[] bytes = json.getBytes() ;
            HttpPost.post(bytes);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            HttpClUnit.clientOver() ;
        }
    }
    @Override
    public void destroy() {
    }
    @Override
    public boolean isDestroy() {
        return false;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/RtuData4HAC_NBhV2_5.java
New file
@@ -0,0 +1,46 @@
package com.dy.testClient.httpCl;
import com.dy.common.util.ByteUtil;
public class RtuData4HAC_NBhV2_5 {
    public byte[] create(String imei) throws Exception{
        /*
         * 0101
         * 00
         * 02
         * 4643
         * 3C
         * 00BE
         * FF
         * 86AB62626E642F332F30026A313233343536373839300D1A64B8FCE60E655554432B3801634E42680719016E110112655056332E30136C56332E30345F32323034323214001701A762626E652F38302F3001020600101A00000000171A00000000181A1A00000000181F00A462626E652F38312F30030101000201A462626E652F38322F30000001000200A262626E652F38342F30001A00015180A462626E652F39392F30016F3836333331383036303136393235390D3903010E390013
         * EA77
         *
         */
        String hex = "0101024570753C001AFFA30D1B000001898AB2E3160E655554432B3862626E642F332F303190" ;
        //String hex = "0101000246433C00BEFF86AB62626E642F332F30026A313233343536373839300D1A64B8FCE60E655554432B3801634E42680719016E110112655056332E30136C56332E30345F32323034323214001701A762626E652F38302F3001020600101A00000000171A00000000181A1A00000000181F00A462626E652F38312F30030101000201A462626E652F38322F30000001000200A262626E652F38342F30001A00015180A462626E652F39392F30016F3836333331383036303136393235390D3903010E390013EA77" ;
        return ByteUtil.hex2Bytes(hex) ;
    }
    /*
     *
86AB62626E642F332F30
026A3132333435363738
39300D1A64B8FCE60E65
5554432B3801634E4268
0719016E110112655056
332E30136C56332E3034
5F323230343232140017
01A762626E652F38302F
3001020600101A000000
00171A00000000181A1A
00000000181F00A46262
6E652F38312F30030101
000201A462626E652F38
322F30000001000200A2
62626E652F38342F3000
1A00015180A462626E65
2F39392F30016F383633
33313830363031363932
35390D3903010E390013
     */
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/RtuData4MeterV1_0.java
New file
@@ -0,0 +1,165 @@
package com.dy.testClient.httpCl;
import com.dy.common.mw.protocol.pMeterV1_0_1.ProtocolConstantV1_0_1;
import com.dy.common.util.ByteUtil;
import com.dy.common.util.ByteUtilUnsigned;
import com.dy.common.util.CreateRadom;
import com.dy.common.util.DateTime;
public class RtuData4MeterV1_0 {
    public byte[] create(String imei) throws Exception{
        /*
         * 68
         * 0051
         * 01
         * 0300000000000001
         * 12233445566778
         * 01
         * 221128152107
         * 0001E240
         * 000004D2
         * 24
         * 0129
         * 11
         * 002D
         * 0035
         * 003D
         * 006E
         * 0038
         * 00C3
         * 00AC
         * 004C
         * 0028
         * 0081
         * 001B
         * 005E
         * 003D
         * 0063
         * 00AB
         * 0071
         * 00BB
         * 0046
         * 004A
         * 009B
         * 0087
         * 00BE
         * 0022
         * 00B0
         * DA
         * 16
         */
        int len = 89 ;
        byte[] bs = new byte[len] ;
        bs[0] = ProtocolConstantV1_0_1.P_Head_Byte ;
        ByteUtilUnsigned.short2Bytes_BE(bs, len, 1);//长度
        bs[3] = (byte)101 ;//协议版本号
        while(true){
            if(imei.length() >= 16){
                break ;
            }else{
                imei = "0" + imei ;
            }
        }
        ByteUtil.string2BCD_BE(bs, imei, 4) ;//IMEI号
        String meterNo = "" + (Long.valueOf(imei) + 1);
        while(true){
            if(meterNo.length() >= 16){
                break ;
            }else{
                meterNo = "0" + meterNo ;
            }
        }
        ByteUtil.string2BCD_BE(bs, meterNo, 12) ;//水表号
        bs[20] = 1 ;//功能码
        ByteUtil.string2BCD_BE(bs, DateTime.yyMMddhhmmss(), 21) ;//时间
        ByteUtilUnsigned.int2Bytes_BE(bs, 123456, 27);//实时累计水量
        ByteUtilUnsigned.int2Bytes_BE(bs, 54321, 31);//日累计水量
        bs[35] = (byte)36;//电池电压
        ByteUtilUnsigned.short2Bytes_BE(bs, 297, 36);//信号强度
        byte sta = 0 ;
        int num = CreateRadom.radom_4() ;
        if(num%2 == 0){
            sta += 1 ;//阀门状态
        }
        num = CreateRadom.radom_4() ;
        if(num%2 == 0){
            sta += 4 ;//阀门故障
        }
        num = CreateRadom.radom_4() ;
        if(num%2 == 0){
            sta += 8 ;//强磁
        }
        num = CreateRadom.radom_4() ;
        if(num%2 == 0){
            sta += 16 ;//电池欠压
        }
        bs[38] = sta;//表状态
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 39);//1点小时用水量
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 41);//2点小时用水量
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 43);//3
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 45);//4
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 47);//5
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 49);//6
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 51);//7
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 53);//8
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 55);//9
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 57);//10
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 59);//11
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 61);//12
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 63);//13
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 65);//14
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 67);//15
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 69);//16
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 71);//17
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 73);//18
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 75);//19
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 77);//20
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 79);//21
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 81);//22
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 83);//23
        num = CreateRadom.radom(200, 10) ;
        ByteUtilUnsigned.short2Bytes_BE(bs, num, 85);//24
        byte he = 0 ;
        for(byte i = 0 ; i <= 86; i++){
            he = (byte)(he + bs[i]) ;
        }
        ByteUtilUnsigned.byte2Byte(bs, he, 87) ;
        bs[88] = ProtocolConstantV1_0_1.P_Tail_Byte ;
        return bs ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/TestBase64.java
New file
@@ -0,0 +1,23 @@
package com.dy.testClient.httpCl;
import java.io.UnsupportedEncodingException;
import java.util.Base64;
import com.dy.common.util.ByteUtil;
public class TestBase64 {
    public static void main(String[] args) throws UnsupportedEncodingException{
        String hex1 = "6838363235393230353934333439373000002002303231310000000000000032003005002E000000000001000000000200000000032101010012330400300521010100123306016907016908000009FF0000FC16" ;
        System.out.println(hex1);
        byte[] bs = ByteUtil.hex2Bytes(hex1) ;
        bs = Base64.getEncoder().encode(bs) ;
        String base64 = new String(bs, "UTF-8") ;
        System.out.println(base64);
        bs = Base64.getDecoder().decode(base64);
        String hex2 = ByteUtil.bytes2Hex(bs, false) ;
        System.out.println(hex2);
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/UpDataPayloadVo.java
New file
@@ -0,0 +1,16 @@
package com.dy.testClient.httpCl;
public class UpDataPayloadVo {
    public String APPdata ;
    public String getAPPdata() {
        return APPdata;
    }
    public void setAPPdata(String aPPdata) {
        APPdata = aPPdata;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/httpCl/UpDataVo.java
New file
@@ -0,0 +1,174 @@
package com.dy.testClient.httpCl;
import com.alibaba.fastjson2.JSON;
public class UpDataVo {
    public Integer upPacketSN; //:-1,
    public Integer upDataSN; //:-1,
    public String topic; //:"v1/up/ad",
    public Long timestamp; //:1667302244541,
    public String tenantId; //:"2000114347",
    public String serviceId; //:"",
    public String protocol; //:"lwm2m",
    public String productId; //:"15410798",
    public UpDataPayloadVo payload; //:{"APPdata":"pQAYWhAGFQEmECIgETMgIQEBACASARckZFoAAFeq"},
    public String messageType; //:"dataReport",
    public String deviceType; //:"",
    public String deviceId; //:"59a4d90bf7a04aeea4d3523fe15d6f3f",
    public String assocAssetId; //:"",
    public String imsi; //:"undefined",
    public String imei; //:"862592059434970"
    public UpDataVo(String imei, String deviceId){
        this.upPacketSN = - 1 ;
        this.upDataSN = - 1 ;
        this.topic = "v1/up/ad" ;
        this.timestamp = System.currentTimeMillis() ;
        this.tenantId = "2000114347" ;
        this.serviceId = "" ;
        this.protocol = "lwm2m" ;
        this.productId = "15410798" ;
        this.messageType = "dataReport" ;
        this.deviceType = "" ;
        this.deviceId = deviceId ;
        this.assocAssetId = "" ;
        this.imsi = "" ;
        this.imei = imei ;
    }
    public String toString(){
        StringBuffer sb = new StringBuffer() ;
        sb.append("\nproductId:" + productId + "\n") ;
        sb.append("deviceId:" + deviceId + "\n") ;
        sb.append("imei:" + imei + "\n") ;
        sb.append("payload:" + (payload==null?"":payload.APPdata) + "\n") ;
        sb.append("timestamp:" + timestamp + "\n") ;
        return sb.toString() ;
    }
    /**
     * 对象转成json
     * @return json
     * @throws Exception 异常
     */
    public String toJson()throws Exception{
        try{
            return JSON.toJSONString(this) ;
            //return new JSONSerializer().exclude(new String[]{"class", "*.class"}).deepSerialize(this);
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    /**
     * json转成对象
     * @param json json
     * @return 对象
     * @throws Exception 异常
     */
    public static UpDataVo jsonToObject(String json)throws Exception{
        try{
            return JSON.parseObject(json, UpDataVo.class) ;
            //return new JSONDeserializer<UpDataVo>()
            //        .use("payload", UpDataPayloadVo.class)
            //        .deserialize(json, UpDataVo.class) ;
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    public Integer getUpPacketSN() {
        return upPacketSN;
    }
    public void setUpPacketSN(Integer upPacketSN) {
        this.upPacketSN = upPacketSN;
    }
    public Integer getUpDataSN() {
        return upDataSN;
    }
    public void setUpDataSN(Integer upDataSN) {
        this.upDataSN = upDataSN;
    }
    public String getTopic() {
        return topic;
    }
    public void setTopic(String topic) {
        this.topic = topic;
    }
    public Long getTimestamp() {
        return timestamp;
    }
    public void setTimestamp(Long timestamp) {
        this.timestamp = timestamp;
    }
    public String getTenantId() {
        return tenantId;
    }
    public void setTenantId(String tenantId) {
        this.tenantId = tenantId;
    }
    public String getServiceId() {
        return serviceId;
    }
    public void setServiceId(String serviceId) {
        this.serviceId = serviceId;
    }
    public String getProtocol() {
        return protocol;
    }
    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }
    public String getProductId() {
        return productId;
    }
    public void setProductId(String productId) {
        this.productId = productId;
    }
    public UpDataPayloadVo getPayload() {
        return payload;
    }
    public void setPayload(UpDataPayloadVo payload) {
        this.payload = payload;
    }
    public String getMessageType() {
        return messageType;
    }
    public void setMessageType(String messageType) {
        this.messageType = messageType;
    }
    public String getDeviceType() {
        return deviceType;
    }
    public void setDeviceType(String deviceType) {
        this.deviceType = deviceType;
    }
    public String getDeviceId() {
        return deviceId;
    }
    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }
    public String getAssocAssetId() {
        return assocAssetId;
    }
    public void setAssocAssetId(String assocAssetId) {
        this.assocAssetId = assocAssetId;
    }
    public String getIMSI() {
        return imsi;
    }
    public void setIMSI(String iMSI) {
        imsi = iMSI;
    }
    public String getIMEI() {
        return imei;
    }
    public void setIMEI(String iMEI) {
        imei = iMEI;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/Code.java
New file
@@ -0,0 +1,15 @@
package com.dy.testClient.rmiClient;
public class Code {
    public static String cd1 = "001" ;//注册
    public static String cd2 = "002" ;//请求sepTest的配置
    public static String cd3 = "003" ;//请求开始工作
    public static String cd4 = "004" ;//向服务端上报信息
    public static String cd5 = "005" ;//向服务端上报  数据上报工作已经完成
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/ResConfigVo.java
New file
@@ -0,0 +1,84 @@
package com.dy.testClient.rmiClient;
import com.alibaba.fastjson2.JSON;
public class ResConfigVo {
    //模拟客户的RtuAddr起始号
    public Long rtuAddrStart = 0L ;
    //模拟客户的IMEI号截止号
    public Long rtuAddrEnd = 0L ;
    //服务端IP
    public String serverIp = "" ;
    //服务端上下文
    public Integer serverPort = 0 ;
    //发送数据次数
    public Integer sendTimes = 0 ;
    /**
     * 对象转成json
     * @return 对象json
     * @throws Exception 异常
     */
    public String toJson()throws Exception{
        try{
            return JSON.toJSONString(this) ;
            //return new JSONSerializer().exclude(new String[]{"class", "*.class"}).deepSerialize(this);
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    /**
     * json转成对象
     * @param json json
     * @return 对象
     * @throws Exception 异常
     */
    public static ResConfigVo jsonToObject(String json)throws Exception{
        try{
            return JSON.parseObject(json, ResConfigVo.class) ;
            //return new JSONDeserializer<ResConfigVo>().deserialize(json, ResConfigVo.class) ;
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    public Long getRtuAddrStart() {
        return rtuAddrStart;
    }
    public void setRtuAddrStart(Long rtuAddrStart) {
        this.rtuAddrStart = rtuAddrStart;
    }
    public Long getRtuAddrEnd() {
        return rtuAddrEnd;
    }
    public void setRtuAddrEnd(Long rtuAddrEnd) {
        this.rtuAddrEnd = rtuAddrEnd;
    }
    public String getServerIp() {
        return serverIp;
    }
    public void setServerIp(String serverIp) {
        this.serverIp = serverIp;
    }
    public Integer getServerPort() {
        return serverPort;
    }
    public void setServerPort(Integer serverPort) {
        this.serverPort = serverPort;
    }
    public Integer getSendTimes() {
        return sendTimes;
    }
    public void setSendTimes(Integer sendTimes) {
        this.sendTimes = sendTimes;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/ResRegisterVo.java
New file
@@ -0,0 +1,45 @@
package com.dy.testClient.rmiClient;
import com.alibaba.fastjson2.JSON;
public class ResRegisterVo {
    public String token ;
    /**
     * 对象转成json
     * @return json
     * @throws Exception 异常
     */
    public String toJson()throws Exception{
        try{
            return JSON.toJSONString(this) ;
            //return new JSONSerializer().exclude(new String[]{"class", "*.class"}).deepSerialize(this);
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    /**
     * json转成对象
     * @param json json
     * @return 对象
     * @throws Exception 异常
     */
    public static ResRegisterVo jsonToObject(String json)throws Exception{
        try{
            return JSON.parseObject(json, ResRegisterVo.class) ;
            //return new JSONDeserializer<ResRegisterVo>().deserialize(json, ResRegisterVo.class) ;
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    public String getToken() {
        return token;
    }
    public void setToken(String id) {
        this.token = id;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/ResStartVo.java
New file
@@ -0,0 +1,47 @@
package com.dy.testClient.rmiClient;
import com.alibaba.fastjson2.JSON;
public class ResStartVo {
    public boolean start ;
    /**
     * 对象转成json
     * @return json
     * @throws Exception 异常
     */
    public String toJson()throws Exception{
        try{
            return JSON.toJSONString(this) ;
            //return new JSONSerializer().exclude(new String[]{"class", "*.class"}).deepSerialize(this);
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    /**
     * json转成对象
     * @param json json
     * @return 对象
     * @throws Exception 异常
     */
    public static ResStartVo jsonToObject(String json)throws Exception{
        try{
            return JSON.parseObject(json, ResStartVo.class) ;
            //return new JSONDeserializer<ResStartVo>().deserialize(json, ResStartVo.class) ;
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    public boolean isStart() {
        return start;
    }
    public void setStart(boolean start) {
        this.start = start;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiClUnit.java
New file
@@ -0,0 +1,268 @@
package com.dy.testClient.rmiClient;
import com.dy.testClient.ServerProperties;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.dy.common.mw.UnitAdapterInterface;
import com.dy.common.mw.UnitInterface;
import com.dy.common.mw.UnitStartedCallbackInterface;
import com.dy.common.mw.channel.rmi.RmiFrameWork;
public class RmiClUnit  implements UnitInterface {
    private static final Logger log = LogManager.getLogger(RmiClUnit.class) ;
    private static final String id = "" + System.nanoTime() ;//自己的id
    public static String token ;//服务端发的token
    private static final RmiClUnit instance = new RmiClUnit() ;
    private static RmiFrameWork frmWork = null ;
    public static RmiClUnitAdapter adapter ;
    public static RmiClUnitConfigVo confVo ;
    private RmiClUnit(){}
    public static RmiClUnit getInstance(){
        return instance ;
    }
    @Override
    public void setAdapter(UnitAdapterInterface adapter) throws Exception {
        if(adapter == null){
            throw new Exception("Rmi Client模块适配器对象不能为空!") ;
        }
        RmiClUnit.adapter = (RmiClUnitAdapter)adapter ;
        RmiClUnit.confVo = RmiClUnit.adapter.getConfig() ;
        if(RmiClUnit.confVo == null){
            throw new Exception("Rmi Client模块配置对象不能为空!") ;
        }
    }
    @Override
    public void start(UnitStartedCallbackInterface callback) throws Exception {
        System.out.println("Rmi Client模块成功启动");
        this.doStart();
        callback.call(null) ;
    }
    @Override
    public void stop(UnitStartedCallbackInterface callback) throws Exception {
        callback.call(null);
    }
    private void doStart(){
        new Thread(() -> {
            while(true){
                try {
                    Thread.sleep(100L);
                    frmWork = getRmiFrameWork() ;
                    if(frmWork != null){
                        break ;
                    }
                } catch (Exception e) {
                    log.error("得到rmiFramWork失败" + e.getMessage());
                    continue ;
                }
            }
            register(frmWork) ;
        }).start();
    }
    public RmiFrameWork getRmiFrameWork(){
        RmiClient rmiCl = new RmiClient(confVo.svUrl, confVo.svPort, confVo.svContext) ;
        return rmiCl.getRmiInterface() ;
    }
    //把上报数据的数量上报给mwTestServer
    public void reportHadReportCount(Integer count){
        try {
            Thread.sleep(100L);
            RmiRequestVo rqVo = new RmiRequestVo() ;
            rqVo.id = id ;
            rqVo.token = token ;
            rqVo.code = Code.cd4 ;
            rqVo.count = count ;
            String json = rqVo.toJson() ;
            frmWork.syncRequest(json) ;
        } catch (Exception e) {
            log.error("把上报数据的数量上报给mwTestServer失败" + e.getMessage());
        }
    }
    //把数据上报完成情况  上报给mwTestServer
    public void reportHadReportOver(Long seconds){
        try {
            Thread.sleep(100L);
            RmiRequestVo rqVo = new RmiRequestVo() ;
            rqVo.id = id ;
            rqVo.token = token ;
            rqVo.code = Code.cd5 ;
            rqVo.over = true ;
            rqVo.seconds = seconds ;
            String json = rqVo.toJson() ;
            frmWork.syncRequest(json) ;
        } catch (Exception e) {
            log.error("把数据上报完成情况  上报给mwTestServer失败" + e.getMessage());
        }
    }
    //向mwTestServer注册
    private void register(RmiFrameWork frmWork){
        boolean error = false ;
        while(true){
            try {
                Thread.sleep(100L);
                RmiRequestVo rqVo = new RmiRequestVo() ;
                rqVo.id = id ;
                rqVo.code = Code.cd1 ;
                String json = rqVo.toJson() ;
                Object rObj = frmWork.syncRequest(json) ;
                if(rObj != null){
                    RmiResponseVo rspVo = RmiResponseVo.jsonToObject(String.valueOf(rObj), ResRegisterVo.class) ;
                    if(rspVo != null){
                        if(rspVo.success){
                            if(rspVo.obj != null && rspVo.obj instanceof ResRegisterVo){
                                ResRegisterVo rVo = (ResRegisterVo)rspVo.obj ;
                                token = rVo.token ;
                                log.info("注册成功,得到token=" + token);
                                break ;
                            }else{
                                log.error("rmi注册失败:服务端返回ResRegisterVo为null");
                                error = true ;
                            }
                        }else{
                            log.error("rmi注册失败:服务端返回错误:" + rspVo.errorInfo);
                            error = true ;
                        }
                    }else{
                        log.error("rmi注册失败:服务端返回的RmiResponseVo为null");
                        error = true ;
                    }
                }else{
                    log.error("rmi注册失败:服务端返回json为null");
                    error = true ;
                }
            } catch (Exception e) {
                log.error("rmi注册失败" + e.getMessage());
                error = true ;
                continue ;
            }
        }
        if(!error){
            getConfig(frmWork) ;
        }
    }
    //从mwTestServer得到配置
    private void getConfig(RmiFrameWork frmWork){
        boolean error = false ;
        while(true){
            try {
                Thread.sleep(100L);
                RmiRequestVo rqVo = new RmiRequestVo() ;
                rqVo.id = id ;
                rqVo.token = token ;
                rqVo.code = Code.cd2 ;
                String json = rqVo.toJson() ;
                Object rObj = frmWork.syncRequest(json) ;
                if(rObj != null){
                    RmiResponseVo rspVo = RmiResponseVo.jsonToObject(String.valueOf(rObj), ResConfigVo.class) ;
                    if(rspVo != null){
                        if(rspVo.success){
                            if(rspVo.obj != null && rspVo.obj instanceof ResConfigVo){
                                ResConfigVo rVo = (ResConfigVo)rspVo.obj ;
                                if(rVo != null){
                                    ServerProperties.rtuAddrStart = rVo.rtuAddrStart;
                                    ServerProperties.rtuAddrEnd = rVo.rtuAddrEnd;
                                    ServerProperties.serverIp = rVo.serverIp;
                                    ServerProperties.serverPort = rVo.serverPort;
                                    ServerProperties.sendTimes = rVo.sendTimes ;
                                    log.info("得到配置成功");
                                    log.info("    开始RtuAddr=" + ServerProperties.rtuAddrStart);
                                    log.info("    截止RtuAddr=" + ServerProperties.rtuAddrEnd);
                                    log.info("    mwAccept服务IP=" + ServerProperties.serverIp);
                                    log.info("    mwAccept服务端口=" + ServerProperties.serverPort);
                                    log.info("    每imei上报数据次数=" + ServerProperties.sendTimes);
                                    break ;
                                }else{
                                    log.error("rmi得到配置失败:json转ResConfigVo为null");
                                    error = true ;
                                }
                            }else{
                                log.error("rmi得到配置失败:服务端返回ResConfigVo为null");
                                error = true ;
                            }
                        }else{
                            log.error("rmi得到配置失败:服务端返回错误:" + rspVo.errorInfo);
                            error = true ;
                        }
                    }else{
                        log.error("rmi得到配置失败:服务端返回的RmiResponseVo为null");
                        error = true ;
                    }
                }else{
                    log.error("rmi得到配置失败:服务端返回json为null");
                    error = true ;
                }
            } catch (Exception e) {
                log.error("rmi得到配置失败" + e.getMessage());
                error = true ;
                continue ;
            }
        }
        if(!error){
            getStart(frmWork) ;
        }
    }
    //从mwTestServer得到开始上报数据的请允许
    private void getStart(RmiFrameWork frmWork){
        log.info("等待服务端允许上报数据");
        while(true){
            try {
                Thread.sleep(100L);
                RmiRequestVo rqVo = new RmiRequestVo() ;
                rqVo.id = id ;
                rqVo.token = token ;
                rqVo.code = Code.cd3 ;
                String json = rqVo.toJson() ;
                Object rObj = frmWork.syncRequest(json) ;
                if(rObj != null){
                    RmiResponseVo rspVo = RmiResponseVo.jsonToObject(String.valueOf(rObj), ResStartVo.class) ;
                    if(rspVo != null){
                        if(rspVo.success){
                            if(rspVo.obj != null && rspVo.obj instanceof ResStartVo){
                                ResStartVo rVo = (ResStartVo)rspVo.obj ;
                                if(rVo != null){
                                    if(rVo.start){
                                        ServerProperties.startWork = true ;
                                        log.info("允许上报数据工作了( ^_^ )");
                                        break ;
                                    }
                                }else{
                                    log.error("rmi请求启动失败:json转ResStartVo为null");
                                }
                            }else{
                                log.error("rmi请求启动失败:服务端返回ResStartVo为null");
                            }
                        }else{
                            log.error("rmi请求启动失败:服务端返回错误:" + rspVo.errorInfo);
                        }
                    }else{
                        log.error("rmi请求启动失败:服务端返回的RmiResponseVo为null");
                    }
                }else{
                    log.error("rmi请求启动失败:服务端返回json为null");
                }
            } catch (Exception e) {
                log.error("rmi请求启动失败" + e.getMessage());
                continue ;
            }
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiClUnitAdapter.java
New file
@@ -0,0 +1,10 @@
package com.dy.testClient.rmiClient;
import com.dy.common.mw.UnitAdapterInterface;
public interface RmiClUnitAdapter  extends UnitAdapterInterface {
    public RmiClUnitConfigVo getConfig()  ;
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiClUnitConfigVo.java
New file
@@ -0,0 +1,29 @@
package com.dy.testClient.rmiClient;
public class RmiClUnitConfigVo {
    public String svUrl ;
    public String svContext ;
    public Integer svPort ;
    public String getSvUrl() {
        return svUrl;
    }
    public void setSvUrl(String svUrl) {
        this.svUrl = svUrl;
    }
    public String getSvContext() {
        return svContext;
    }
    public void setSvContext(String svContext) {
        this.svContext = svContext;
    }
    public Integer getSvPort() {
        return svPort;
    }
    public void setSvPort(Integer svPort) {
        this.svPort = svPort;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiClient.java
New file
@@ -0,0 +1,40 @@
package com.dy.testClient.rmiClient;
import java.rmi.Naming;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.dy.common.mw.channel.rmi.RmiFrameWork;
public class RmiClient {
    private static Logger log = LogManager.getLogger(RmiClient.class.getName()) ;
    private String rmiServerIp;
    private Integer rmiServerPort;
    private String rmiServerContext ;
    public RmiClient(String rmiServerIp, Integer rmiServerPort, String rmiServerContext){
        this.rmiServerIp = rmiServerIp ;
        this.rmiServerPort = rmiServerPort ;
        this.rmiServerContext = rmiServerContext ;
    }
    /**
     * 得到中间件RMI
     * @return
     */
    @SuppressWarnings("finally")
    public RmiFrameWork getRmiInterface() {
        String rmiServerUrl = "rmi://" + this.rmiServerIp + ":" + this.rmiServerPort + "/" + this.rmiServerContext ;
        RmiFrameWork rmiIntf = null;
        try {
            rmiIntf = (RmiFrameWork) Naming.lookup(rmiServerUrl);
        } catch (Exception e) {
            log.error("连接RMI服务:" + rmiServerUrl + "时出错。", e);
        } finally {
            return rmiIntf;
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiRequestVo.java
New file
@@ -0,0 +1,96 @@
package com.dy.testClient.rmiClient;
import com.alibaba.fastjson2.JSON;
public class RmiRequestVo {
    public String id ;
    public String token ;
    public String code ;
    public Integer count;//aepTest上报数据数量
    public Boolean over ;//aepTest上报数据结束
    public Long seconds ;//aepTest上报数据用时(秒)
    /**
     * 对象转成json
     * @return json
     * @throws Exception 异常
     */
    public String toJson()throws Exception{
        try{
            return JSON.toJSONString(this) ;
            //return new JSONSerializer().exclude(new String[]{"class", "*.class"}).deepSerialize(this);
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    /**
     * json转成对象
     * @param json json
     * @return 对象
     * @throws Exception 异常
     */
    public static RmiRequestVo jsonToObject(String json)throws Exception{
        try{
            return JSON.parseObject(json, RmiRequestVo.class) ;
            //JSONDeserializer<RmiRequestVo> jsonD = new JSONDeserializer<RmiRequestVo>() ;
            //RmiRequestVo rqVo = jsonD.deserialize(json, RmiRequestVo.class) ;
            //return rqVo ;
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getToken() {
        return token;
    }
    public void setToken(String token) {
        this.token = token;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public Integer getCount() {
        return count;
    }
    public void setCount(Integer count) {
        this.count = count;
    }
    public Boolean getOver() {
        return over;
    }
    public void setOver(Boolean over) {
        this.over = over;
    }
    public Long getSeconds() {
        return seconds;
    }
    public void setSeconds(Long seconds) {
        this.seconds = seconds;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/rmiClient/RmiResponseVo.java
New file
@@ -0,0 +1,77 @@
package com.dy.testClient.rmiClient;
import com.alibaba.fastjson2.JSON;
public class RmiResponseVo {
    public boolean success = true ;
    public String errorInfo ;
    public String code ;
    public Object obj ;
    /**
     * 对象转成json
     * @return json
     * @throws Exception 异常
     */
    public String toJson()throws Exception{
        try{
            return JSON.toJSONString(this) ;
            //return new JSONSerializer().exclude(new String[]{"class", "*.class"}).deepSerialize(this);
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    /**
     * json转成对象
     * @param json
     * @return 对象
     * @throws Exception 异常
     */
    public static RmiResponseVo jsonToObject(String json, Class<?> clazz)throws Exception{
        try{
            return JSON.parseObject(json, RmiResponseVo.class) ;
            //JSONDeserializer<RmiResponseVo> jsonD = new JSONDeserializer<RmiResponseVo>() ;
            //jsonD.use("obj", clazz) ;
            //RmiResponseVo resp = jsonD.deserialize(json, RmiResponseVo.class) ;
            //return resp ;
        }catch(Exception e){
            throw new Exception(e.getMessage() , e ) ;
        }
    }
    public boolean isSuccess() {
        return success;
    }
    public void setSuccess(boolean success) {
        this.success = success;
    }
    public String getErrorInfo() {
        return errorInfo;
    }
    public void setErrorInfo(String errorInfo) {
        this.errorInfo = errorInfo;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public Object getObj() {
        return obj;
    }
    public void setObj(Object obj) {
        this.obj = obj;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/MyThreadJob.java
New file
@@ -0,0 +1,55 @@
package com.dy.testClient.tcpClient;
import com.dy.common.threadPool.ThreadPool;
import com.dy.testClient.httpCl.*;
import java.util.Base64;
public class MyThreadJob  implements ThreadPool.Job {
    public String rtuAddr;
    public MyThreadJob(){
    }
    public MyThreadJob(String rtuAddr){
        this.rtuAddr = rtuAddr ;
    }
    @Override
    public void execute() throws Exception {
        testP206V1_0_0() ;
    }
    private void testP206V1_0_0(){
        try{
            RtuData4MeterV1_0 rd = new RtuData4MeterV1_0() ;
            byte[] bs = rd.create(rtuAddr) ;
            bs = Base64.getEncoder().encode(bs) ;
            UpDataPayloadVo payloadVo = new UpDataPayloadVo() ;
            payloadVo.APPdata = new String(bs, "UTF-8") ;
            UpDataVo vo = new UpDataVo(rtuAddr, "8086" + rtuAddr) ;
            vo.payload = payloadVo ;
            String json = vo.toJson() ;
            byte[] bytes = json.getBytes() ;
            HttpPost.post(bytes);
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            HttpClUnit.clientOver() ;
        }
    }
    @Override
    public void destroy() {
    }
    @Override
    public boolean isDestroy() {
        return false;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/TcpClUnit.java
New file
@@ -0,0 +1,110 @@
package com.dy.testClient.tcpClient;
import com.dy.common.mw.UnitAdapterInterface;
import com.dy.common.mw.UnitInterface;
import com.dy.common.mw.UnitStartedCallbackInterface;
import com.dy.common.threadPool.ThreadPool;
import com.dy.common.threadPool.TreadPoolFactory;
import com.dy.testClient.ServerProperties;
import com.dy.testClient.rmiClient.RmiClUnit;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class TcpClUnit  implements UnitInterface {
    private static final Logger log = LogManager.getLogger(TcpClUnit.class) ;
    private static TcpClUnit instance = new TcpClUnit() ;
    public static TcpClUnitAdapter adapter ;
    public static TcpClUnitConfigVo confVo ;
    private static ThreadPool.Pool pool ;
    private static Integer totalRunedClientCount = 0;
    private static Integer totalOverClientCount = 0;
    private static Long startTime = 0L ;
    private TcpClUnit(){} ;
    public static TcpClUnit getInstance(){
        return instance ;
    }
    @Override
    public void setAdapter(UnitAdapterInterface adapter) throws Exception {
        if(adapter == null){
            throw new Exception("Tcp Client模块适配器对象不能为空!") ;
        }
        TcpClUnit.adapter = (TcpClUnitAdapter)adapter ;
        TcpClUnit.confVo = TcpClUnit.adapter.getConfig() ;
        if(TcpClUnit.confVo == null){
            throw new Exception("Tcp Client模块配置对象不能为空!") ;
        }
    }
    @Override
    public void start(UnitStartedCallbackInterface callback) throws Exception {
        pool = TreadPoolFactory.getThreadPoolLong() ;
        System.out.println("Tcp Client模块成功启动");
        this.doStart();
        callback.call(null) ;
    }
    @Override
    public void stop(UnitStartedCallbackInterface callback) throws Exception {
        callback.call(null);
    }
    private void doStart(){
        new Thread(new Runnable(){
            @Override
            public void run() {
                try {
                    while(true){
                        if(!ServerProperties.startWork){
                            Thread.sleep(100L);
                        }else{
                            startTime = System.currentTimeMillis() ;
                            for(Long addr = ServerProperties.rtuAddrStart; addr <= ServerProperties.rtuAddrEnd; addr++){
                                totalRunedClientCount++ ;
                                startClient(addr) ;
                            }
                            while(true){
                                if(totalOverClientCount.longValue() >= totalRunedClientCount.longValue()){
                                    Long seconds = (System.currentTimeMillis() - startTime)/1000 ;
                                    RmiClUnit.getInstance().reportHadReportOver(seconds) ;
                                    System.out.println("共用时" + seconds + "秒");
                                    break ;
                                }else{
                                    Thread.sleep(100L);
                                }
                            }
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    private void startClient(Long rtuAddr){
        try {
            pool.putJob(new MyThreadJob("" + rtuAddr));
        } catch (Exception e) {
            log.error("TcpClUnit.startClient() ", e);
        }
    }
    public static synchronized void clientOver(){
        totalOverClientCount++;
        if(totalOverClientCount % 100 == 0){
            RmiClUnit.getInstance().reportHadReportCount(totalOverClientCount);
            System.out.println("已经发送" + totalOverClientCount * + "条数据");
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/TcpClUnitAdapter.java
New file
@@ -0,0 +1,7 @@
package com.dy.testClient.tcpClient;
import com.dy.common.mw.UnitAdapterInterface;
public interface TcpClUnitAdapter extends UnitAdapterInterface {
    public TcpClUnitConfigVo getConfig() ;
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpClient/TcpClUnitConfigVo.java
New file
@@ -0,0 +1,7 @@
package com.dy.testClient.tcpClient;
public class TcpClUnitConfigVo {
    public boolean enable ;
    public int heartbeatTimes ;
    public int sendInterval ;
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/LocalCodecFactory.java
New file
@@ -0,0 +1,35 @@
package com.dy.testClient.tcpConnect;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.core.session.IoSession;
public class LocalCodecFactory implements ProtocolCodecFactory {
    private ProtocolEncoder encoder;
    private ProtocolDecoder decoder;
    public LocalCodecFactory() {
        encoder = new LocalEncoder();
        decoder = new LocalDecoder();
    }
    /**
     * 得到协议编码器
     * @param ioSession 网络会话
     * @return 协议编码器
     */
    @Override
    public ProtocolEncoder getEncoder(IoSession ioSession) {
        return encoder;
    }
    /**
     * 得到协议解码器
     * @param ioSession 网络会话
     * @return 协议解码器
     */
    @Override
    public ProtocolDecoder getDecoder(IoSession ioSession) {
        return decoder;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/LocalDecoder.java
New file
@@ -0,0 +1,91 @@
package com.dy.testClient.tcpConnect;
import java.io.*;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import com.am.cs12.command.*;
public class LocalDecoder extends CumulativeProtocolDecoder {
    private static final String DECODER_STATE_KEY = LocalDecoder.class.getName() + ".STATE";
    public static final int MAX_SIZE = 2147483647 ;
    private class DecoderState {
        Command com;
    }
    /**
     * 对网络传输来的数据进行解码
     */
    protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws IOException, Exception{
        //从会话中得到已经解码的数据
        DecoderState decoderState = (DecoderState) session.getAttribute(DECODER_STATE_KEY);
        if (decoderState == null) {
            decoderState = new DecoderState();
            session.setAttribute(DECODER_STATE_KEY, decoderState);
        }
        if (decoderState.com == null) {
            //试着读取命令区域数据
            //MAX_IMAGE_SIZE 目的是防止大数据量攻击
            if (in.prefixedDataAvailable(4, MAX_SIZE)) {
                decoderState.com = readCommand(in);
            } else {
                //命令区域无足够的数据
                return false;
            }
        }
        if (decoderState.com != null) {
            //试着读取数据(文件)区域数据
            //MAX_IMAGE_SIZE 目的是防止大数据量攻击
            if (in.prefixedDataAvailable(4, MAX_SIZE)) {
                byte[] bs = getDataBytes(in);
                MinaData minaCom = new MinaData() ;
                minaCom.setCom(decoderState.com) ;
                minaCom.setAttachment(bs) ;
                out.write(minaCom);
                decoderState.com = null;
                return true;
            } else {
                //数据(文件)区域无足够的数据
                return false;
            }
        }
        return false;
    }
    /**
     * 读取Command命令
     * @param in
     * @return
     * @throws IOException
     */
    private Command readCommand(IoBuffer iob) throws IOException , Exception{
        int length = iob.getInt();
        byte[] bytes = new byte[length];
        iob.get(bytes);
        Command    com = new Command().toObject(bytes);
        return com;
    }
    /**
     * 得到数据域数据的字节数组
     * @param in
     * @return
     * @throws IOException
     */
    private byte[] getDataBytes(IoBuffer iob) throws IOException {
        int length = iob.getInt();
        if(length == 0){
            return null ;
        }
        byte[] bytes = new byte[length];
        iob.get(bytes);
        return bytes ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/LocalEncoder.java
New file
@@ -0,0 +1,51 @@
package com.dy.testClient.tcpConnect;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import java.io.*;
public class LocalEncoder extends ProtocolEncoderAdapter {
    /**
     * 对数据进行编码,以备网络传输
     */
    public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws IOException, Exception{
        MinaData minaData = null ;
        if(message instanceof Command){
            minaData = new MinaData() ;
            minaData.setCom((Command)message) ;
        }else{
            minaData = (MinaData) message;
        }
        byte[] bytes1 = getCommandBytes(minaData.getCom());
        byte[] bytes2 = minaData.getAttachment() ;
        int capacity = (bytes1==null?0:bytes1.length) + (bytes2==null?0:bytes2.length) + 8;
        IoBuffer buffer = IoBuffer.allocate(capacity, false);
        buffer.putInt(bytes1.length);
        buffer.put(bytes1);
        if(bytes2 == null){
            buffer.putInt(0);
        }else{
            buffer.putInt(bytes2.length);
            buffer.put(bytes2);
        }
        buffer.flip();
        out.write(buffer);
    }
    /**
     * 将命令转换成字节数组
     * @param com
     * @return
     * @throws IOException
     * @throws Exception
     */
    private byte[] getCommandBytes(Command com) throws IOException, Exception {
        String xml = com.toXml() ;
        byte[] bytes = xml.getBytes() ;
        return bytes ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/MinaConnect.java
New file
@@ -0,0 +1,55 @@
package com.dy.testClient.tcpConnect;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.SocketConnector;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import java.net.InetSocketAddress;
public class MinaConnect {
    /**
     * 判断会话是否有效
     * @param se 网络会话
     * @return 是否连接
     */
    protected boolean isConnected(IoSession se) {
        return (se != null && se.isConnected());
    }
    /**
     * 创建新会话
     * @param host 服务器URI
     * @param port 服务器端口
     * @return 网络会话
     */
    protected IoSession createSession(String host , int port , int connectTimeout , MinaHandler handler) throws Exception{
        SocketConnector connector = new NioSocketConnector();
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new LocalCodecFactory()));
        connector.setHandler(handler);
        ConnectFuture connectFuture = connector.connect(new InetSocketAddress(host, port));
        connectFuture.awaitUninterruptibly(connectTimeout);
        IoSession se = connectFuture.getSession();
        return se ;
    }
    /**
     * 关闭会话联接
     * @param se
     * @param connectTimeout
     */
    protected void disconnect(IoSession se , int connectTimeout) {
        if (se != null) {
            try{
                se.closeNow().awaitUninterruptibly(connectTimeout);
            }catch(Exception e){
            }finally{
                se = null;
            }
        }
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/MinaConnectPool.java
New file
@@ -0,0 +1,107 @@
package com.dy.testClient.tcpConnect;
import java.util.*;
import org.apache.mina.core.session.IoSession;
public class MinaConnectPool {
    /**
     * 空闲会话的池(Hashtable是线程安全的)
     */
    private static Hashtable<String , Vector<IoSession>> freeSessions = new Hashtable<String ,Vector<IoSession>>();
    /**
     * 从会话池中得到空闲的会话,如果没有空闲的会话,本着快速反应的原则,新建一个会话,不再等待繁忙会话的释放
     * @param host
     * @param port
     * @return
     * @throws Exception
     */
    public static IoSession getSession(String host , int port , int connectTimeout) throws Exception{
        Vector<IoSession> vecter = freeSessions.get(getKey(host , port)) ;
        if(vecter == null){
            vecter = new Vector<IoSession>() ;
            freeSessions.put(getKey(host , port), vecter) ;
        }
        MinaConnect con = new MinaConnect() ;
        IoSession se = popSession(vecter , con) ;
        if(se == null){
            MinaHandler handler = new MinaHandler(connectTimeout) ;
            se = createNewSession(host, port, connectTimeout, con, handler) ;
        }
        return se ;
    }
    /**
     * 将会话放回池中
     * @param host
     * @param port
     * @param se
     */
    public static void freeSession(String host , int port , IoSession se){
        if(se == null){
            return ;
        }
        Vector<IoSession> vecter = freeSessions.get(getKey(host , port)) ;
        if(vecter == null){
            vecter = new Vector<IoSession>() ;
            freeSessions.put(getKey(host , port), vecter) ;
        }
        putSession(vecter, se) ;
    }
    /**
     * 从会话池中取得空闲的会话
     * @param vecter
     * @return
     */
    private static IoSession popSession(Vector<IoSession> vecter , MinaConnect con){
        IoSession se = null ;
        while(se == null && !vecter.isEmpty()){
            se = (IoSession)vecter.firstElement() ;
            if(se != null){
                vecter.removeElementAt(0) ;
            }
            if(!con.isConnected(se)){
                se = null ;
            }
        }
        return se ;
    }
    /**
     * 放新会话
     * @param vecter
     * @param se
     */
    private static void putSession(Vector<IoSession> vecter , IoSession se){
        vecter.addElement(se) ;
    }
    /**
     * 创建新会话
     * @param host
     * @param port
     * @param connectTimeout
     * @param con
     * @return
     * @throws Exception
     */
    private static IoSession createNewSession(String host , int port , int connectTimeout, MinaConnect con , MinaHandler handler) throws Exception{
        return con.createSession(host, port, connectTimeout , handler) ;
    }
    /**
     * 得到会话池的key
     * @param url
     * @param port
     * @return
     */
    private static String getKey(String host , int port){
        return host + port ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/java/com/dy/testClient/tcpConnect/MinaHandler.java
New file
@@ -0,0 +1,94 @@
package com.dy.testClient.tcpConnect;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
public class MinaHandler extends IoHandlerAdapter {
    private static Logger log = LogManager.getLogger(MinaHandler.class.getName()) ;
    private Object synObj ;
    private int connectTimeout ;
    private MinaData minaData ;
    public MinaHandler( int connectTimeout){
        this.connectTimeout = connectTimeout ;
        this.synObj = new Object() ;
    }
    /**
     * 发送命令
     * @param session
     * @param minaData
     */
    public void sendCommand(IoSession session, MinaData minaData){
        session.write(minaData) ;
    }
    /**
     * 取得命令结果
     * @param waitTimeout
     */
    public MinaData getAnswer(int waitTimeout){
        synchronized (synObj) {
            try {
                synObj.wait(waitTimeout);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return this.minaData;
    }
    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        new MinaConnect().disconnect(session, this.connectTimeout) ;
        log.error(cause.getMessage()) ;
    }
    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        this.minaData = (MinaData) message;
        synchronized (synObj) {
            if (synObj != null) {
                synObj.notifyAll();
            }
        }
    }
    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        super.messageSent(session, message);
        log.info("命令已经发送。") ;
    }
    @Override
    public void sessionClosed(IoSession session) throws Exception {
        super.sessionClosed(session);
        log.info("网络会话已经关闭。") ;
    }
    @Override
    public void sessionCreated(IoSession session) throws Exception {
        super.sessionCreated(session);
        log.info("网络会话已经创建。") ;
    }
    @Override
    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
        super.sessionIdle(session, status);
    }
    @Override
    public void sessionOpened(IoSession session) throws Exception {
        super.sessionOpened(session);
        log.info("网络会话已经打开。") ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/resources/Config.xml
New file
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<config>
    <server name="RTU测试客户端" showStartInfo="true" company="http://www.dyjs.com"/>
    <!--
    支持模块
    短工作时长线程池,线程负责用时较短的工作任务
    short_maxThread: 池中最大线程数为所有CPU核数+1(short池与long池各分一半),若为-1,不受限制 ,设置为0,表示不启动线程池
    short_minThread: 池中最小线程数,若为-1,不受限制,设置为0,表示不启动线程池
    short_freeTimeout: 线程数空闲时长,若池中线程数量大于minThread,且有的线程空闲时长超过freeTimeout,则清除该线程,为了不清除,把minThread与maxThread设置相等
    short_busyTimeout:线程不间断工作时长(单位为秒)超时限,认为线程已经了崩溃,将强制清除,短工作时长设置为5秒
    长工作时长线程池,线程负责用时较长的工作任务,例如数据库存取操作
    long_maxThread: 池中最大线程数为所有CPU核数+1(short池与long池各分一半),若为-1,不受限制,设置为0,表示不启动线程池
    long_minThread: 池中最小线程数,若为-1,不受限制,设置为0,表示不启动线程池
    long_freeTimeout: 线程数空闲时长,若池中线程数量大于minThread,且有的线程空闲时长超过freeTimeout,则清除该线程
    long_busyTimeout:线程不间断工作时长(单位为秒)超时限,若为-1,不受限制
    enableThreadPool:是否启用线程池
     -->
    <!-- 当前实现,写rtu日志、RMI数据处理用到了短线程池  -->
    <!-- 当前实现,rtu上行数据处理(读写数据)用到了第线程池  -->
    <support
            short_maxThread="0"
            short_minThread="0"
            short_freeTimeout="60"
            short_busyTimeout="5"
            long_maxThread="13"
            long_minThread="13"
            long_freeTimeout="60"
            long_busyTimeout="-1"
    />
    <!--
    rmi客户端
     -->
    <rmiCl
        rmiSvUrl="127.0.0.1"
        rmiSvContext="mwTestServer"
        rmiSvPort="9898"
    />
    <!--
    enable:是否启动
    heartbeatTimes:连续配置次数心跳后发送一次数据
    sendInterval:发送心跳或数据的时间间隔
     -->
    <tcpCl
        enable="true"
        heartbeatTimes="3"
        sendInterval="3"
    />
</config>
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/resources/application.yml
New file
@@ -0,0 +1 @@
pipIrr-platform/pipIrr-mw/pipIrr-mwTest-client/src/main/resources/log4j2.yml
New file
@@ -0,0 +1,64 @@
Configuration:
    #status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出;可以设置成Off(关闭)或Error(只输出错误信息)
    status: Error
    Properties: # 定义全局变量
        Property:
            #日志文件存储的目录
            - name: log.path
              value: ./logs
            #日志文件存储名称
            - name: project.name
              value: mwTestClient
    #定义输出器,可以输出到控制台和文件.
    Appenders:
        #输出到控制台
        Console:
            #Appender命名
            name: CONSOLE
            target: SYSTEM_OUT
            ThresholdFilter:
                level: debug #输出日志级别,输出日志时,首先由Loggers.Root.level或Loggers.Logger.level判断是否输出,然后再由本level判断是否输出
                onMatch: ACCEPT #onMatch=ACCEPT 大于等于 "level" 配置的等级地日志输出
                onMismatch: DENY #onMismatch=DENY 小于 "level" 配置的等级地日志不输出
            #日志内容样式
            PatternLayout:
                #%n-换行
                #%m-日志内容,输出代码中指定的日志信息
                #%p-输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
                #%r-程序启动到现在的毫秒数
                #%%- 输出一个"%" 字符
                #%t-当前线程名
                #%d-日期和时间, 常用的格式有%d{DATE},%d{ABSOLUTE},%d{HH:mm:ss,SSS},%d{ddMMyyyyHH:mm:ss,SSS}
                #%l-同%F%L%C%M
                #%F-java源文件名
                #%L-java源码行数
                #%C-java类名,%C{1}输出最后一个元素
                #%M-java方法名
                pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS}:%4p %t (%C.%M:%L) - %m%n"
        # 输出到文件,超过10MB归档
        RollingFile:
            - name: ROLLING_FILE
              ignoreExceptions: false
              fileName: ${log.path}/${project.name}.log
              filePattern: "${log.path}/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.log.gz"
              ThresholdFilter:
                  level: error #输出日志级别,输出日志时,首先由Loggers.Root.level或Loggers.Logger.level判断是否输出,然后再由本level判断是否输出
                  onMatch: ACCEPT #onMatch=ACCEPT 大于等于 "level" 配置的等级地日志输出
                  onMismatch: DENY #onMismatch=DENY 小于 "level" 配置的等级地日志不输出
              #日志内容样式
              PatternLayout:
                  pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS}:%4p %t (%C.%M:%L) - %m%n"
              Policies:
                  SizeBasedTriggeringPolicy:
                      size: "10 MB"
              DefaultRolloverStrategy:
                  max: 1000
    Loggers:
        Root:
            level: info #日志输出级别,共有8个级别,按照从低到高为:all < trace < debug < info < warn < error < fatal < off
            AppenderRef: #Root的子节点,用来指定该日志输出到哪个Appender.
                - ref: CONSOLE #输出日志时,首先由本level判断是否输出,然后再由上面的Appenders.Console.ThresholdFilter.level判断是否输出
                - ref: ROLLING_FILE  #输出日志时,首先由本level判断是否输出,然后再由上面的Appenders.RollingFile.ThresholdFilter.level判断是否输出