New file |
| | |
| | | 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/ |
New file |
| | |
| | | <?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> |
New file |
| | |
| | | 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 ; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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 ; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | 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(); |
| | | } |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | 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 ; |
| | | } |
New file |
| | |
| | | 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 + "条数据"); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.dy.testClient.httpCl; |
| | | |
| | | import com.dy.common.mw.UnitAdapterInterface; |
| | | |
| | | public interface HttpClUnitAdapter extends UnitAdapterInterface { |
| | | |
| | | public HttpClUnitConfigVo getConfig() ; |
| | | |
| | | } |
New file |
| | |
| | | package com.dy.testClient.httpCl; |
| | | |
| | | public class HttpClUnitConfigVo { |
| | | public boolean enable ; |
| | | } |
New file |
| | |
| | | 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) ; |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | 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 |
| | | */ |
| | | |
| | | } |
New file |
| | |
| | | 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 ; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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); |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.dy.testClient.httpCl; |
| | | |
| | | public class UpDataPayloadVo { |
| | | |
| | | public String APPdata ; |
| | | |
| | | |
| | | public String getAPPdata() { |
| | | return APPdata; |
| | | } |
| | | |
| | | public void setAPPdata(String aPPdata) { |
| | | APPdata = aPPdata; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | 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" ;//向服务端上报 数据上报工作已经完成 |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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 ; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.dy.testClient.rmiClient; |
| | | |
| | | import com.dy.common.mw.UnitAdapterInterface; |
| | | |
| | | public interface RmiClUnitAdapter extends UnitAdapterInterface { |
| | | |
| | | public RmiClUnitConfigVo getConfig() ; |
| | | |
| | | } |
| | | |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | 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 * + "条数据"); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.dy.testClient.tcpClient; |
| | | |
| | | import com.dy.common.mw.UnitAdapterInterface; |
| | | |
| | | public interface TcpClUnitAdapter extends UnitAdapterInterface { |
| | | public TcpClUnitConfigVo getConfig() ; |
| | | } |
New file |
| | |
| | | package com.dy.testClient.tcpClient; |
| | | |
| | | public class TcpClUnitConfigVo { |
| | | public boolean enable ; |
| | | public int heartbeatTimes ; |
| | | public int sendInterval ; |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
New file |
| | |
| | | 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 ; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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 ; |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | 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 ; |
| | | } |
| | | |
| | | } |
| | | |
New file |
| | |
| | | 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("网络会话已经打开。") ; |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | <?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> |
New file |
| | |
| | | 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判断是否输出 |