mirror of
https://gitee.com/farsunset/cim.git
synced 2025-07-24 08:41:46 +08:00
修复push消息时连续for循环中推送时,android , java 客户端会收不到消息的问题
This commit is contained in:
parent
f3b7ec63e0
commit
5dc06714ff
@ -25,45 +25,45 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.2.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.2.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.4.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.2.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.12.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.12.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.29" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
|
||||
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.2.4.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.2.4.RELEASE" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.25" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.29" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.29" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.29" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.2.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.31" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.31" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.31" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.18.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.2.4.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.4.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.4.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.2.4.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.4.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.2.5.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.29" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.2.2.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.2.4.RELEASE" level="project" />
|
||||
<orderEntry type="module-library">
|
||||
<library name="Maven: com.farsunset:cim-server-sdk:3.8.0">
|
||||
<CLASSES>
|
||||
@ -74,7 +74,7 @@
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="Maven: org.apache.mina:mina-core:2.1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.29" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.35.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.35.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.35.Final" level="project" />
|
||||
|
@ -77,6 +77,23 @@
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
<component name="libraryTable">
|
||||
<library name="Maven: ch.qos.logback:logback-classic:1.2.3">
|
||||
<CLASSES>
|
||||
@ -111,70 +128,70 @@
|
||||
<root url="jar://$MAVEN_REPOSITORY$/cn/teaey/apns4j/apns4j/1.1.4/apns4j-1.1.4-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.1">
|
||||
<library name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.2">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.10.1/jackson-annotations-2.10.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.10.2/jackson-annotations-2.10.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.10.1/jackson-annotations-2.10.1-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.10.2/jackson-annotations-2.10.2-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.10.1/jackson-annotations-2.10.1-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.10.2/jackson-annotations-2.10.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.1">
|
||||
<library name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.10.1/jackson-core-2.10.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.10.2/jackson-core-2.10.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.10.1/jackson-core-2.10.1-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.10.2/jackson-core-2.10.2-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.10.1/jackson-core-2.10.1-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.10.2/jackson-core-2.10.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.1">
|
||||
<library name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.2">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.10.1/jackson-databind-2.10.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.10.2/jackson-databind-2.10.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.10.1/jackson-databind-2.10.1-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.10.2/jackson-databind-2.10.2-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.10.1/jackson-databind-2.10.1-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.10.2/jackson-databind-2.10.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.1">
|
||||
<library name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.2">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.10.1/jackson-datatype-jdk8-2.10.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.10.2/jackson-datatype-jdk8-2.10.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.10.1/jackson-datatype-jdk8-2.10.1-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.10.2/jackson-datatype-jdk8-2.10.2-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.10.1/jackson-datatype-jdk8-2.10.1-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.10.2/jackson-datatype-jdk8-2.10.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.1">
|
||||
<library name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.2">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.10.1/jackson-datatype-jsr310-2.10.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.10.2/jackson-datatype-jsr310-2.10.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.10.1/jackson-datatype-jsr310-2.10.1-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.10.2/jackson-datatype-jsr310-2.10.2-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.10.1/jackson-datatype-jsr310-2.10.1-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.10.2/jackson-datatype-jsr310-2.10.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.1">
|
||||
<library name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.2">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-parameter-names/2.10.1/jackson-module-parameter-names-2.10.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-parameter-names/2.10.2/jackson-module-parameter-names-2.10.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-parameter-names/2.10.1/jackson-module-parameter-names-2.10.1-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-parameter-names/2.10.2/jackson-module-parameter-names-2.10.2-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-parameter-names/2.10.1/jackson-module-parameter-names-2.10.1-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-parameter-names/2.10.2/jackson-module-parameter-names-2.10.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: com.fasterxml:classmate:1.5.1">
|
||||
@ -298,15 +315,15 @@
|
||||
<root url="jar://$MAVEN_REPOSITORY$/jakarta/annotation/jakarta.annotation-api/1.3.5/jakarta.annotation-api-1.3.5-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: jakarta.validation:jakarta.validation-api:2.0.1">
|
||||
<library name="Maven: jakarta.validation:jakarta.validation-api:2.0.2">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/jakarta/validation/jakarta.validation-api/2.0.1/jakarta.validation-api-2.0.1.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/jakarta/validation/jakarta.validation-api/2.0.2/jakarta.validation-api-2.0.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/jakarta/validation/jakarta.validation-api/2.0.1/jakarta.validation-api-2.0.1-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/jakarta/validation/jakarta.validation-api/2.0.2/jakarta.validation-api-2.0.2-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/jakarta/validation/jakarta.validation-api/2.0.1/jakarta.validation-api-2.0.1-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/jakarta/validation/jakarta.validation-api/2.0.2/jakarta.validation-api-2.0.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.apache.commons:commons-lang3:3.8.1">
|
||||
@ -353,37 +370,37 @@
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/mina/mina-core/2.1.3/mina-core-2.1.3-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.29">
|
||||
<library name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.31">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-core/9.0.29/tomcat-embed-core-9.0.29.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-core/9.0.31/tomcat-embed-core-9.0.31.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-core/9.0.29/tomcat-embed-core-9.0.29-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-core/9.0.31/tomcat-embed-core-9.0.31-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-core/9.0.29/tomcat-embed-core-9.0.29-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-core/9.0.31/tomcat-embed-core-9.0.31-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.29">
|
||||
<library name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.31">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-el/9.0.29/tomcat-embed-el-9.0.29.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-el/9.0.31/tomcat-embed-el-9.0.31.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-el/9.0.29/tomcat-embed-el-9.0.29-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-el/9.0.31/tomcat-embed-el-9.0.31-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-el/9.0.29/tomcat-embed-el-9.0.29-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-el/9.0.31/tomcat-embed-el-9.0.31-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.29">
|
||||
<library name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.31">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.29/tomcat-embed-websocket-9.0.29.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.31/tomcat-embed-websocket-9.0.31.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.29/tomcat-embed-websocket-9.0.29-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.31/tomcat-embed-websocket-9.0.31-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.29/tomcat-embed-websocket-9.0.29-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.31/tomcat-embed-websocket-9.0.31-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.freemarker:freemarker:2.3.29">
|
||||
@ -419,224 +436,224 @@
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jboss/logging/jboss-logging/3.4.1.Final/jboss-logging-3.4.1.Final-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.slf4j:jul-to-slf4j:1.7.29">
|
||||
<library name="Maven: org.slf4j:jul-to-slf4j:1.7.30">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/jul-to-slf4j/1.7.29/jul-to-slf4j-1.7.29.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/jul-to-slf4j/1.7.30/jul-to-slf4j-1.7.30.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/jul-to-slf4j/1.7.29/jul-to-slf4j-1.7.29-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/jul-to-slf4j/1.7.30/jul-to-slf4j-1.7.30-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/jul-to-slf4j/1.7.29/jul-to-slf4j-1.7.29-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/jul-to-slf4j/1.7.30/jul-to-slf4j-1.7.30-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.slf4j:slf4j-api:1.7.29">
|
||||
<library name="Maven: org.slf4j:slf4j-api:1.7.30">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.29/slf4j-api-1.7.29.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.29/slf4j-api-1.7.29-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.29/slf4j-api-1.7.29-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.5.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-autoconfigure/2.2.2.RELEASE/spring-boot-autoconfigure-2.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-autoconfigure/2.2.5.RELEASE/spring-boot-autoconfigure-2.2.5.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-autoconfigure/2.2.2.RELEASE/spring-boot-autoconfigure-2.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-autoconfigure/2.2.5.RELEASE/spring-boot-autoconfigure-2.2.5.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-autoconfigure/2.2.2.RELEASE/spring-boot-autoconfigure-2.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-autoconfigure/2.2.5.RELEASE/spring-boot-autoconfigure-2.2.5.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.2.5.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-freemarker/2.2.2.RELEASE/spring-boot-starter-freemarker-2.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-freemarker/2.2.5.RELEASE/spring-boot-starter-freemarker-2.2.5.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-freemarker/2.2.2.RELEASE/spring-boot-starter-freemarker-2.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-freemarker/2.2.5.RELEASE/spring-boot-starter-freemarker-2.2.5.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-freemarker/2.2.2.RELEASE/spring-boot-starter-freemarker-2.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-freemarker/2.2.5.RELEASE/spring-boot-starter-freemarker-2.2.5.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.5.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-json/2.2.2.RELEASE/spring-boot-starter-json-2.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-json/2.2.5.RELEASE/spring-boot-starter-json-2.2.5.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-json/2.2.2.RELEASE/spring-boot-starter-json-2.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-json/2.2.5.RELEASE/spring-boot-starter-json-2.2.5.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-json/2.2.2.RELEASE/spring-boot-starter-json-2.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-json/2.2.5.RELEASE/spring-boot-starter-json-2.2.5.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-logging:2.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-logging:2.2.5.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-logging/2.2.2.RELEASE/spring-boot-starter-logging-2.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-logging/2.2.5.RELEASE/spring-boot-starter-logging-2.2.5.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-logging/2.2.2.RELEASE/spring-boot-starter-logging-2.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-logging/2.2.5.RELEASE/spring-boot-starter-logging-2.2.5.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-logging/2.2.2.RELEASE/spring-boot-starter-logging-2.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-logging/2.2.5.RELEASE/spring-boot-starter-logging-2.2.5.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.2.5.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-tomcat/2.2.2.RELEASE/spring-boot-starter-tomcat-2.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-tomcat/2.2.5.RELEASE/spring-boot-starter-tomcat-2.2.5.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-tomcat/2.2.2.RELEASE/spring-boot-starter-tomcat-2.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-tomcat/2.2.5.RELEASE/spring-boot-starter-tomcat-2.2.5.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-tomcat/2.2.2.RELEASE/spring-boot-starter-tomcat-2.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-tomcat/2.2.5.RELEASE/spring-boot-starter-tomcat-2.2.5.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.5.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-validation/2.2.2.RELEASE/spring-boot-starter-validation-2.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-validation/2.2.5.RELEASE/spring-boot-starter-validation-2.2.5.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-validation/2.2.2.RELEASE/spring-boot-starter-validation-2.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-validation/2.2.5.RELEASE/spring-boot-starter-validation-2.2.5.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-validation/2.2.2.RELEASE/spring-boot-starter-validation-2.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-validation/2.2.5.RELEASE/spring-boot-starter-validation-2.2.5.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.5.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-web/2.2.2.RELEASE/spring-boot-starter-web-2.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-web/2.2.5.RELEASE/spring-boot-starter-web-2.2.5.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-web/2.2.2.RELEASE/spring-boot-starter-web-2.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-web/2.2.5.RELEASE/spring-boot-starter-web-2.2.5.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-web/2.2.2.RELEASE/spring-boot-starter-web-2.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter-web/2.2.5.RELEASE/spring-boot-starter-web-2.2.5.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter:2.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework.boot:spring-boot-starter:2.2.5.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter/2.2.2.RELEASE/spring-boot-starter-2.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter/2.2.5.RELEASE/spring-boot-starter-2.2.5.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter/2.2.2.RELEASE/spring-boot-starter-2.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter/2.2.5.RELEASE/spring-boot-starter-2.2.5.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter/2.2.2.RELEASE/spring-boot-starter-2.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-starter/2.2.5.RELEASE/spring-boot-starter-2.2.5.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework.boot:spring-boot:2.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework.boot:spring-boot:2.2.5.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot/2.2.2.RELEASE/spring-boot-2.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot/2.2.5.RELEASE/spring-boot-2.2.5.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot/2.2.2.RELEASE/spring-boot-2.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot/2.2.5.RELEASE/spring-boot-2.2.5.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot/2.2.2.RELEASE/spring-boot-2.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot/2.2.5.RELEASE/spring-boot-2.2.5.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework:spring-aop:5.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework:spring-aop:5.2.4.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/5.2.2.RELEASE/spring-aop-5.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/5.2.4.RELEASE/spring-aop-5.2.4.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/5.2.2.RELEASE/spring-aop-5.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/5.2.4.RELEASE/spring-aop-5.2.4.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/5.2.2.RELEASE/spring-aop-5.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-aop/5.2.4.RELEASE/spring-aop-5.2.4.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework:spring-beans:5.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework:spring-beans:5.2.4.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/5.2.2.RELEASE/spring-beans-5.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/5.2.4.RELEASE/spring-beans-5.2.4.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/5.2.2.RELEASE/spring-beans-5.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/5.2.4.RELEASE/spring-beans-5.2.4.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/5.2.2.RELEASE/spring-beans-5.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-beans/5.2.4.RELEASE/spring-beans-5.2.4.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework:spring-context-support:5.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework:spring-context-support:5.2.4.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context-support/5.2.2.RELEASE/spring-context-support-5.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context-support/5.2.4.RELEASE/spring-context-support-5.2.4.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context-support/5.2.2.RELEASE/spring-context-support-5.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context-support/5.2.4.RELEASE/spring-context-support-5.2.4.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context-support/5.2.2.RELEASE/spring-context-support-5.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context-support/5.2.4.RELEASE/spring-context-support-5.2.4.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework:spring-context:5.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework:spring-context:5.2.4.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/5.2.2.RELEASE/spring-context-5.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/5.2.4.RELEASE/spring-context-5.2.4.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/5.2.2.RELEASE/spring-context-5.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/5.2.4.RELEASE/spring-context-5.2.4.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/5.2.2.RELEASE/spring-context-5.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-context/5.2.4.RELEASE/spring-context-5.2.4.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework:spring-core:5.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework:spring-core:5.2.4.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/5.2.2.RELEASE/spring-core-5.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/5.2.4.RELEASE/spring-core-5.2.4.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/5.2.2.RELEASE/spring-core-5.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/5.2.4.RELEASE/spring-core-5.2.4.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/5.2.2.RELEASE/spring-core-5.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-core/5.2.4.RELEASE/spring-core-5.2.4.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework:spring-expression:5.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework:spring-expression:5.2.4.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/5.2.2.RELEASE/spring-expression-5.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/5.2.4.RELEASE/spring-expression-5.2.4.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/5.2.2.RELEASE/spring-expression-5.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/5.2.4.RELEASE/spring-expression-5.2.4.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/5.2.2.RELEASE/spring-expression-5.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-expression/5.2.4.RELEASE/spring-expression-5.2.4.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework:spring-jcl:5.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework:spring-jcl:5.2.4.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jcl/5.2.2.RELEASE/spring-jcl-5.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jcl/5.2.4.RELEASE/spring-jcl-5.2.4.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jcl/5.2.2.RELEASE/spring-jcl-5.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jcl/5.2.4.RELEASE/spring-jcl-5.2.4.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jcl/5.2.2.RELEASE/spring-jcl-5.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-jcl/5.2.4.RELEASE/spring-jcl-5.2.4.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework:spring-web:5.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework:spring-web:5.2.4.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/5.2.2.RELEASE/spring-web-5.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/5.2.4.RELEASE/spring-web-5.2.4.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/5.2.2.RELEASE/spring-web-5.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/5.2.4.RELEASE/spring-web-5.2.4.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/5.2.2.RELEASE/spring-web-5.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-web/5.2.4.RELEASE/spring-web-5.2.4.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.springframework:spring-webmvc:5.2.2.RELEASE">
|
||||
<library name="Maven: org.springframework:spring-webmvc:5.2.4.RELEASE">
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/5.2.2.RELEASE/spring-webmvc-5.2.2.RELEASE.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/5.2.4.RELEASE/spring-webmvc-5.2.4.RELEASE.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/5.2.2.RELEASE/spring-webmvc-5.2.2.RELEASE-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/5.2.4.RELEASE/spring-webmvc-5.2.4.RELEASE-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/5.2.2.RELEASE/spring-webmvc-5.2.2.RELEASE-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-webmvc/5.2.4.RELEASE/spring-webmvc-5.2.4.RELEASE-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
<library name="Maven: org.yaml:snakeyaml:1.25">
|
||||
|
@ -23,7 +23,6 @@
|
||||
<component name="ProjectId" id="1PxWQToGq56jcmMz176UjXWLSaU" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showExcludedFiles" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
@ -34,7 +33,7 @@
|
||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="aspect.path.notification.shown" value="true" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/lib" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||
<property name="node.js.detected.package.eslint" value="true" />
|
||||
<property name="node.js.detected.package.tslint" value="true" />
|
||||
<property name="node.js.path.for.package.eslint" value="project" />
|
||||
@ -74,18 +73,6 @@
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
<component name="ServiceViewManager">
|
||||
<option name="viewStates">
|
||||
<list>
|
||||
<serviceView>
|
||||
<treeState>
|
||||
<expand />
|
||||
<select />
|
||||
</treeState>
|
||||
</serviceView>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="SvnConfiguration">
|
||||
<configuration />
|
||||
</component>
|
||||
@ -115,13 +102,23 @@
|
||||
<workItem from="1568597528002" duration="523000" />
|
||||
<workItem from="1579076046499" duration="14355000" />
|
||||
<workItem from="1579226829168" duration="8852000" />
|
||||
<workItem from="1583472574255" duration="526000" />
|
||||
<workItem from="1583473153031" duration="14749000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="1" />
|
||||
<option name="version" value="2" />
|
||||
</component>
|
||||
<component name="WindowStateProjectService">
|
||||
<state x="609" y="345" key="#com.intellij.fileTypes.FileTypeChooser" timestamp="1583567210548">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state x="609" y="345" key="#com.intellij.fileTypes.FileTypeChooser/0.23.1920.1057@0.23.1920.1057" timestamp="1583567210548" />
|
||||
<state x="645" y="287" key="#com.intellij.openapi.updateSettings.impl.PluginUpdateInfoDialog" timestamp="1583472646530">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state x="645" y="287" key="#com.intellij.openapi.updateSettings.impl.PluginUpdateInfoDialog/0.23.1920.1057@0.23.1920.1057" timestamp="1583472646530" />
|
||||
<state x="627" y="209" key="#com.intellij.refactoring.safeDelete.UnsafeUsagesDialog" timestamp="1579149988674">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
@ -130,38 +127,46 @@
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state x="690" y="218" key="FileChooserDialogImpl/0.0.1920.1040@0.0.1920.1040" timestamp="1579230010253" />
|
||||
<state width="1867" height="615" key="GridCell.Tab.0.bottom" timestamp="1579243696749">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.0.bottom" timestamp="1583566851136">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state width="1867" height="615" key="GridCell.Tab.0.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1579243696749" />
|
||||
<state width="1867" height="615" key="GridCell.Tab.0.center" timestamp="1579243696749">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.0.bottom/0.23.1920.1057@0.23.1920.1057" timestamp="1583566851136" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.0.center" timestamp="1583566851135">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state width="1867" height="615" key="GridCell.Tab.0.center/0.0.1920.1040@0.0.1920.1040" timestamp="1579243696749" />
|
||||
<state width="1867" height="615" key="GridCell.Tab.0.left" timestamp="1579243696749">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.0.center/0.23.1920.1057@0.23.1920.1057" timestamp="1583566851135" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.0.left" timestamp="1583566851135">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state width="1867" height="615" key="GridCell.Tab.0.left/0.0.1920.1040@0.0.1920.1040" timestamp="1579243696749" />
|
||||
<state width="1867" height="615" key="GridCell.Tab.0.right" timestamp="1579243696749">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.0.left/0.23.1920.1057@0.23.1920.1057" timestamp="1583566851135" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.0.right" timestamp="1583566851136">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state width="1867" height="615" key="GridCell.Tab.0.right/0.0.1920.1040@0.0.1920.1040" timestamp="1579243696749" />
|
||||
<state width="1867" height="615" key="GridCell.Tab.1.bottom" timestamp="1579243696751">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.0.right/0.23.1920.1057@0.23.1920.1057" timestamp="1583566851136" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.1.bottom" timestamp="1583566851137">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state width="1867" height="615" key="GridCell.Tab.1.bottom/0.0.1920.1040@0.0.1920.1040" timestamp="1579243696751" />
|
||||
<state width="1867" height="615" key="GridCell.Tab.1.center" timestamp="1579243696750">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.1.bottom/0.23.1920.1057@0.23.1920.1057" timestamp="1583566851137" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.1.center" timestamp="1583566851136">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state width="1867" height="615" key="GridCell.Tab.1.center/0.0.1920.1040@0.0.1920.1040" timestamp="1579243696750" />
|
||||
<state width="1867" height="615" key="GridCell.Tab.1.left" timestamp="1579243696749">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.1.center/0.23.1920.1057@0.23.1920.1057" timestamp="1583566851136" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.1.left" timestamp="1583566851136">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state width="1867" height="615" key="GridCell.Tab.1.left/0.0.1920.1040@0.0.1920.1040" timestamp="1579243696749" />
|
||||
<state width="1867" height="615" key="GridCell.Tab.1.right" timestamp="1579243696751">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.1.left/0.23.1920.1057@0.23.1920.1057" timestamp="1583566851136" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.1.right" timestamp="1583566851137">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state width="1867" height="615" key="GridCell.Tab.1.right/0.0.1920.1040@0.0.1920.1040" timestamp="1579243696751" />
|
||||
<state width="1870" height="565" key="GridCell.Tab.1.right/0.23.1920.1057@0.23.1920.1057" timestamp="1583566851137" />
|
||||
<state width="1867" height="386" key="GridCell.Tab.2.bottom" timestamp="1579156159339">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
@ -178,18 +183,20 @@
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state width="1867" height="386" key="GridCell.Tab.2.right/0.0.1920.1040@0.0.1920.1040" timestamp="1579156159339" />
|
||||
<state x="574" y="193" width="771" height="654" key="find.popup" timestamp="1579242964438">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
<state x="574" y="219" width="771" height="670" key="find.popup" timestamp="1583473246286">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state x="574" y="193" width="771" height="654" key="find.popup/0.0.1920.1040@0.0.1920.1040" timestamp="1579242964438" />
|
||||
<state x="574" y="219" width="771" height="670" key="find.popup/0.23.1920.1057@0.23.1920.1057" timestamp="1583473246286" />
|
||||
<state x="161" y="163" key="new project wizard" timestamp="1579242569030">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
</state>
|
||||
<state x="161" y="163" key="new project wizard/0.0.1920.1040@0.0.1920.1040" timestamp="1579242569030" />
|
||||
<state x="539" y="5" width="840" height="1034" key="search.everywhere.popup" timestamp="1579235575382">
|
||||
<screen x="0" y="0" width="1920" height="1040" />
|
||||
<state x="539" y="28" width="840" height="1051" key="search.everywhere.popup" timestamp="1583567214095">
|
||||
<screen x="0" y="23" width="1920" height="1057" />
|
||||
</state>
|
||||
<state x="539" y="5" width="840" height="1034" key="search.everywhere.popup/0.0.1920.1040@0.0.1920.1040" timestamp="1579235575382" />
|
||||
<state x="539" y="28" width="840" height="1051" key="search.everywhere.popup/0.23.1920.1057@0.23.1920.1057" timestamp="1583567214095" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager>
|
||||
@ -204,6 +211,11 @@
|
||||
<line>22</line>
|
||||
<option name="timeStamp" value="10" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" type="java-line">
|
||||
<url>file://$PROJECT_DIR$/src/main/java/com/farsunset/cim/handler/SessionClosedHandler.java</url>
|
||||
<line>48</line>
|
||||
<option name="timeStamp" value="12" />
|
||||
</line-breakpoint>
|
||||
</breakpoints>
|
||||
</breakpoint-manager>
|
||||
</component>
|
||||
|
@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.2.RELEASE</version>
|
||||
<version>2.2.5.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -21,12 +21,11 @@
|
||||
*/
|
||||
package com.farsunset.cim.api.controller;
|
||||
|
||||
import com.farsunset.cim.api.controller.dto.MessageResult;
|
||||
import com.farsunset.cim.push.DefaultMessagePusher;
|
||||
import com.farsunset.cim.sdk.server.model.Message;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -39,30 +38,15 @@ public class MessageController {
|
||||
@Resource
|
||||
private DefaultMessagePusher defaultMessagePusher;
|
||||
|
||||
/**
|
||||
* 此方法仅仅在集群时,通过服务器调用
|
||||
*
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/dispatch")
|
||||
public MessageResult dispatchSend(Message message) {
|
||||
return send(message);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping(value = "/send")
|
||||
public MessageResult send(Message message) {
|
||||
|
||||
MessageResult result = new MessageResult();
|
||||
@PostMapping(value = "/send")
|
||||
public ResponseEntity<Long> send(Message message) {
|
||||
|
||||
message.setId(System.currentTimeMillis());
|
||||
|
||||
defaultMessagePusher.push(message);
|
||||
|
||||
result.id = message.getId();
|
||||
result.timestamp = message.getTimestamp();
|
||||
return result;
|
||||
return ResponseEntity.ok(message.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
/**
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************************
|
||||
* *
|
||||
* Website : http://www.farsunset.com *
|
||||
* *
|
||||
***************************************************************************************
|
||||
*/
|
||||
package com.farsunset.cim.api.controller.dto;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class BaseResult {
|
||||
public int code = HttpStatus.OK.value();
|
||||
public String message;
|
||||
public Object data;
|
||||
public List<?> dataList;
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/**
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************************
|
||||
* *
|
||||
* Website : http://www.farsunset.com *
|
||||
* *
|
||||
***************************************************************************************
|
||||
*/
|
||||
package com.farsunset.cim.api.controller.dto;
|
||||
|
||||
public class MessageResult extends BaseResult {
|
||||
public long timestamp;
|
||||
public long id;
|
||||
}
|
@ -13,7 +13,6 @@ import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
|
||||
@ -23,19 +22,8 @@ public class CIMConfig implements CIMRequestHandler, ApplicationListener<Applica
|
||||
@Resource
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private HashMap<String,Class<? extends CIMRequestHandler>> appHandlerMap = new HashMap<>();
|
||||
private final HashMap<String,CIMRequestHandler> appHandlerMap = new HashMap<>();
|
||||
|
||||
@PostConstruct
|
||||
private void initHandler() {
|
||||
/*
|
||||
* 账号绑定handler
|
||||
*/
|
||||
appHandlerMap.put("client_bind", BindHandler.class);
|
||||
/*
|
||||
* 连接关闭handler
|
||||
*/
|
||||
appHandlerMap.put("client_closed", SessionClosedHandler.class);
|
||||
}
|
||||
|
||||
@Bean(destroyMethod = "destroy")
|
||||
public CIMNioSocketAcceptor getNioSocketAcceptor(@Value("${cim.app.port}") int port,
|
||||
@ -52,28 +40,22 @@ public class CIMConfig implements CIMRequestHandler, ApplicationListener<Applica
|
||||
@Override
|
||||
public void process(CIMSession session, SentBody body) {
|
||||
|
||||
CIMRequestHandler handler = findHandlerByKey(body.getKey());
|
||||
CIMRequestHandler handler = appHandlerMap.get(body.getKey());
|
||||
|
||||
if(handler == null) {return ;}
|
||||
|
||||
handler.process(session, body);
|
||||
|
||||
}
|
||||
|
||||
private CIMRequestHandler findHandlerByKey(String key){
|
||||
Class<? extends CIMRequestHandler> handlerClass = appHandlerMap.get(key);
|
||||
if (handlerClass==null){
|
||||
return null;
|
||||
}
|
||||
return applicationContext.getBean(handlerClass);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* springboot启动完成之后再启动cim服务的,避免服务正在重启时,客户端会立即开始连接导致意外异常发生.
|
||||
*/
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) {
|
||||
|
||||
appHandlerMap.put("client_bind",applicationContext.getBean(BindHandler.class));
|
||||
appHandlerMap.put("client_closed",applicationContext.getBean(SessionClosedHandler.class));
|
||||
|
||||
applicationContext.getBean(CIMNioSocketAcceptor.class).bind();
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -39,7 +39,7 @@ import javax.annotation.Resource;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* 账号绑定实现
|
||||
*
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -33,7 +33,7 @@ import javax.annotation.Resource;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* 断开连接,清除session
|
||||
*
|
||||
*/
|
||||
@ -56,15 +56,7 @@ public class SessionClosedHandler implements CIMRequestHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
CIMSession oldSession = cimSessionService.get(account.toString());
|
||||
|
||||
if (oldSession == null || oldSession.isApnsEnable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
oldSession.setState(CIMSession.STATE_DISABLED);
|
||||
oldSession.setNid(null);
|
||||
cimSessionService.save(oldSession);
|
||||
cimSessionService.remove(account.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -23,13 +23,13 @@ package com.farsunset.cim.push;
|
||||
|
||||
import com.farsunset.cim.sdk.server.model.Message;
|
||||
|
||||
/**
|
||||
/*
|
||||
* 消息发送实接口
|
||||
*
|
||||
*/
|
||||
public interface CIMMessagePusher {
|
||||
|
||||
/**
|
||||
/*
|
||||
* 向用户发送消息
|
||||
*
|
||||
* @param msg
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -31,7 +31,7 @@ import org.springframework.stereotype.Component;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
/*
|
||||
* 消息发送实现类
|
||||
*
|
||||
*/
|
||||
@ -50,7 +50,7 @@ public class DefaultMessagePusher implements CIMMessagePusher {
|
||||
private ApnsService apnsService;
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* 向用户发送消息
|
||||
*
|
||||
* @param message
|
||||
@ -76,9 +76,10 @@ public class DefaultMessagePusher implements CIMMessagePusher {
|
||||
* 如果连接到了其他服务器则转发请求到目标服务器
|
||||
*/
|
||||
if (session.isConnected() && !Objects.equals(host, session.getHost())) {
|
||||
/**
|
||||
/*
|
||||
* @TODO
|
||||
* 在此调用目标服务器接口来发送
|
||||
* 在此调用目标服务器接口来发送,如session.host = 123.123.123.123
|
||||
* 调用目标服务器的消息发送接口http://123.123.123.123:8080/message/send
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
/*
|
||||
* 正式场景下,使用redis或者数据库来存储session信息
|
||||
*/
|
||||
@Repository
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -26,7 +26,7 @@ import com.farsunset.cim.sdk.server.model.CIMSession;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* 集群 session管理实现示例, 各位可以自行实现 AbstractSessionManager接口来实现自己的 session管理 服务器集群时
|
||||
* 须要将CIMSession 信息存入数据库或者redis中 等 第三方存储空间中,便于所有服务器都可以访问
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -46,7 +46,7 @@ public class CIMSessionServiceImpl implements CIMSessionService {
|
||||
sessionRepository.save(session);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
*
|
||||
* @param account 用户id
|
||||
* @return
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -23,10 +23,4 @@ cim.websocket.port=34567
|
||||
|
||||
apple.apns.debug=false
|
||||
apple.apns.p12.password= your p12 password
|
||||
apple.apns.p12.file= /apns/lvxin.p12
|
||||
|
||||
|
||||
##################################################################
|
||||
# System Config #
|
||||
##################################################################
|
||||
sys.message.dispatch.url = http://%1$s:${server.port}/api/message/dispatch
|
||||
apple.apns.p12.file= /apns/lvxin.p12
|
@ -1,67 +1,67 @@
|
||||
module.common.html.title = CIM\u7BA1\u7406\u7CFB\u7EDF
|
||||
module.common.account = \u5e10\u53f7
|
||||
module.common.password = \u5bc6\u7801
|
||||
module.common.save = \u4fdd\u5b58
|
||||
module.common.html.title = CIM管理系统
|
||||
module.common.account = 帐号
|
||||
module.common.password = 密码
|
||||
module.common.save = 保存
|
||||
module.common.id = ID
|
||||
module.common.type =\u7c7b\u578b
|
||||
module.common.name =\u540d\u79f0
|
||||
module.common.time =\u65f6\u95f4
|
||||
module.common.operation =\u64cd\u4f5c
|
||||
module.common.query =\u67e5\u8be2
|
||||
module.common.look =\u67e5\u770b
|
||||
module.common.preview =\u9884\u89c8
|
||||
module.common.send =\u53d1\u9001
|
||||
module.common.saveing = \u6b63\u5728\u4fdd\u5b58,\u8bf7\u7a0d\u5019......
|
||||
module.common.add = \u6dfb\u52a0
|
||||
module.common.update = \u4fee\u6539
|
||||
module.common.delete = \u5220\u9664
|
||||
module.common.save.success = \u4fdd\u5b58\u6210\u529f
|
||||
module.common.delete.success = \u5220\u9664\u6210\u529f
|
||||
module.common.delete.loading =\u6b63\u5728\u5220\u9664,\u8bf7\u7a0d\u5019......
|
||||
module.common.loading = \u52a0\u8f7d\u4e2d,\u8bf7\u7a0d\u5019......
|
||||
module.common.description = \u8bf4\u660e
|
||||
module.common.state = \u72b6\u6001
|
||||
module.common.content = \u5185\u5bb9
|
||||
module.common.location = \u4f4d\u7f6e
|
||||
module.common.longitude = \u7ecf\u5ea6
|
||||
module.common.latitude = \u7eac\u5ea6
|
||||
module.common.sort = \u6392\u5e8f
|
||||
module.common.code = \u7f16\u53f7
|
||||
module.common.import = \u5bfc\u5165
|
||||
module.common.headlogo = \u5934\u50cf
|
||||
module.common.homepage = \u4e3b\u9875
|
||||
module.common.website = \u7f51\u5740
|
||||
module.common.text = \u6587\u5b57
|
||||
module.common.type =类型
|
||||
module.common.name =名称
|
||||
module.common.time =时间
|
||||
module.common.operation =操作
|
||||
module.common.query =查询
|
||||
module.common.look =查看
|
||||
module.common.preview =预览
|
||||
module.common.send =发送
|
||||
module.common.saveing = 正在保存,请稍候......
|
||||
module.common.add = 添加
|
||||
module.common.update = 修改
|
||||
module.common.delete = 删除
|
||||
module.common.save.success = 保存成功
|
||||
module.common.delete.success = 删除成功
|
||||
module.common.delete.loading =正在删除,请稍候......
|
||||
module.common.loading = 加载中,请稍候......
|
||||
module.common.description = 说明
|
||||
module.common.state = 状态
|
||||
module.common.content = 内容
|
||||
module.common.location = 位置
|
||||
module.common.longitude = 经度
|
||||
module.common.latitude = 纬度
|
||||
module.common.sort = 排序
|
||||
module.common.code = 编号
|
||||
module.common.import = 导入
|
||||
module.common.headlogo = 头像
|
||||
module.common.homepage = 主页
|
||||
module.common.website = 网址
|
||||
module.common.text = 文字
|
||||
|
||||
module.global.error.500.hint = \u670d\u52a1\u7a0b\u5e8f\u53d1\u751f\u5185\u90e8\u9519\u8bef
|
||||
module.global.error.400.hint = \u8bf7\u6c42\u53c2\u6570\u7c7b\u578b\u4e0d\u6b63\u786e
|
||||
module.global.error.404.hint = \u8bbf\u95ee\u7684\u8d44\u6e90\u4e0d\u5b58\u5728
|
||||
module.global.pager.next = \u4e0b\u4e00\u9875
|
||||
module.global.pager.previou = \u4e0a\u4e00\u9875
|
||||
module.global.pager.description = \u5171{0}\u6761\u8bb0\u5f55,{1}\u9875
|
||||
|
||||
module.console.about = \u5173\u4e8e
|
||||
module.console.about.version = v3.5.0
|
||||
module.console.about.author = \u4f5c\u8005: \u8fdc\u65b9\u5915\u9633
|
||||
module.console.about.author.wechat = \u5fae\u4fe1: 3979434
|
||||
module.global.error.500.hint = 服务程序发生内部错误
|
||||
module.global.error.400.hint = 请求参数类型不正确
|
||||
module.global.error.404.hint = 访问的资源不存在
|
||||
module.global.pager.next = 下一页
|
||||
module.global.pager.previou = 上一页
|
||||
module.global.pager.description = 共{0}条记录,{1}页
|
||||
|
||||
module.console.about = 关于
|
||||
module.console.about.version = 1.0.0
|
||||
module.console.about.author = 作者: 远方夕阳
|
||||
module.console.about.author.wechat = 微信: 3979434
|
||||
module.console.about.author.qq = Q Q: 3979434
|
||||
module.console.about.copyright = \u57FA\u4E8EJava\u670D\u52A1\u7AEF\u7684\u5373\u65F6\u901A\u4FE1\u89E3\u51B3\u65B9\u6848,\u4E0Eandroid \u5BA2\u6237\u7AEF\u5B8C\u7F8E\u7ED3\u5408\uFF0C\u540C\u65F6\u652F\u6301\u5176\u4ED6\u8BED\u8A00\u7684\u79FB\u52A8\u5E94\u7528\uFF0C\u7269\u8054\u7F51\uFF0C\u667A\u80FD\u5BB6\u5C45\uFF0C\u684C\u9762\u5E94\u7528\uFF0CWEB\u5E94\u7528\u4EE5\u53CA\u540E\u53F0\u7CFB\u7EDF\u4E4B\u95F4\u7684\u5373\u65F6\u6D88\u4EA4\u4E92\uFF0C\u4E3A\u4F60\u89E3\u51B3\u4E86\u957F\u8FDE\u63A5\u5404\u79CD\u6D88\u606F\u4E8B\u4EF6\uFF0C\u65AD\u7EBF\u91CD\u8FDE\u7B49\u7E41\u7410\u7684\u5904\u7406\uFF0C\u4F7F\u7528\u65B9\u4FBF\u6613\u4E8E\u96C6\u6210\u3002<br/><a target="_blank" href="https://gitee.com/farsunset/cim">https://gitee.com/farsunset/cim</a>
|
||||
module.console.menu.onlineuser = \u5728\u7ebf\u7528\u6237
|
||||
|
||||
module.console.cimsession.sending = \u6b63\u5728\u53d1\u9001\uff0c\u8bf7\u7a0d\u5019......
|
||||
module.console.cimsession.send.success = \u53d1\u9001\u6210\u529f
|
||||
module.console.cimsession.logo =\u5934\u50cf
|
||||
module.console.cimsession.account =\u5e10\u53f7
|
||||
module.console.cimsession.nid = \u8fde\u63a5ID
|
||||
module.console.cimsession.channel = \u7ec8\u7aef
|
||||
module.console.cimsession.app.version =\u5e94\u7528\u7248\u672c
|
||||
module.console.cimsession.os.version =\u7cfb\u7edf\u7248\u672c
|
||||
module.console.cimsession.deviceid =\u8bbe\u5907\u7f16\u53f7
|
||||
module.console.cimsession.device.model =\u7ec8\u7aef\u578b\u53f7
|
||||
module.console.cimsession.online.time =\u5728\u7ebf\u65f6\u957f(\u79d2)
|
||||
module.console.cimsession.time.format ={0}\u79d2
|
||||
module.console.about.copyright = 基于Java服务端的即时通信解决方案,与android 客户端完美结合,同时支持其他语言的移动应用,物联网,智能家居,桌面应用,WEB应用以及后台系统之间的即时消交互,为你解决了长连接各种消息事件,断线重连等繁琐的处理,使用方便易于集成。<br/><a target="_blank" href="https://gitee.com/farsunset/cim">https://gitee.com/farsunset/cim</a>
|
||||
module.console.menu.onlineuser = 在线用户
|
||||
|
||||
module.console.cimsession.sending = 正在发送,请稍候......
|
||||
module.console.cimsession.send.success = 发送成功
|
||||
module.console.cimsession.logo =头像
|
||||
module.console.cimsession.account =帐号
|
||||
module.console.cimsession.nid = 连接ID
|
||||
module.console.cimsession.channel = 终端
|
||||
module.console.cimsession.app.version =应用版本
|
||||
module.console.cimsession.os.version =系统版本
|
||||
module.console.cimsession.deviceid =设备编号
|
||||
module.console.cimsession.device.model =终端型号
|
||||
module.console.cimsession.online.time =在线时长(秒)
|
||||
module.console.cimsession.time.format ={0}秒
|
||||
|
||||
module.console.cimsession.send.message =发送消息
|
||||
module.console.cimsession.receiver = 接收帐号
|
||||
module.console.cimsession.message = 消息内容
|
||||
|
||||
module.console.cimsession.send.message =\u53d1\u9001\u6d88\u606f
|
||||
module.console.cimsession.receiver = \u63a5\u6536\u5e10\u53f7
|
||||
module.console.cimsession.message = \u6d88\u606f\u5185\u5bb9
|
||||
|
||||
|
24
cim-client-sdk/cim-android-sdk/cim-android-sdk.iml
Normal file → Executable file
24
cim-client-sdk/cim-android-sdk/cim-android-sdk.iml
Normal file → Executable file
@ -1,2 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4" />
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: com.google.protobuf:protobuf-lite:3.0.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
|
||||
<orderEntry type="module-library">
|
||||
<library name="Maven: android:android:8.0.0">
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/libs/android.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
</component>
|
||||
</module>
|
0
cim-client-sdk/cim-android-sdk/jar.bat
Normal file → Executable file
0
cim-client-sdk/cim-android-sdk/jar.bat
Normal file → Executable file
0
cim-client-sdk/cim-android-sdk/jar.sh
Normal file → Executable file
0
cim-client-sdk/cim-android-sdk/jar.sh
Normal file → Executable file
0
cim-client-sdk/cim-android-sdk/pom.xml
Normal file → Executable file
0
cim-client-sdk/cim-android-sdk/pom.xml
Normal file → Executable file
@ -29,76 +29,74 @@ import android.net.Uri;
|
||||
|
||||
class CIMCacheManager {
|
||||
|
||||
public static final String CIM_CONFIG_INFO = "CIM_CONFIG_INFO";
|
||||
public static final String KEY_ACCOUNT = "KEY_ACCOUNT";
|
||||
|
||||
public static final String KEY_ACCOUNT = "KEY_ACCOUNT";
|
||||
public static final String KEY_DEVICE_ID = "KEY_DEVICE_ID";
|
||||
|
||||
public static final String KEY_DEVICE_ID = "KEY_DEVICE_ID";
|
||||
public static final String KEY_MANUAL_STOP = "KEY_MANUAL_STOP";
|
||||
|
||||
public static final String KEY_MANUAL_STOP = "KEY_MANUAL_STOP";
|
||||
public static final String KEY_CIM_DESTROYED = "KEY_CIM_DESTROYED";
|
||||
|
||||
public static final String KEY_CIM_DESTROYED = "KEY_CIM_DESTROYED";
|
||||
public static final String KEY_CIM_SERVER_HOST = "KEY_CIM_SERVER_HOST";
|
||||
|
||||
public static final String KEY_CIM_SERVER_HOST = "KEY_CIM_SERVER_HOST";
|
||||
public static final String KEY_CIM_SERVER_PORT = "KEY_CIM_SERVER_PORT";
|
||||
|
||||
public static final String KEY_CIM_SERVER_PORT = "KEY_CIM_SERVER_PORT";
|
||||
public static final String KEY_CIM_CONNECTION_STATE = "KEY_CIM_CONNECTION_STATE";
|
||||
|
||||
public static final String KEY_CIM_CONNECTION_STATE = "KEY_CIM_CONNECTION_STATE";
|
||||
public static final String CONTENT_URI = "content://%s.cim.provider";
|
||||
|
||||
public static final String CONTENT_URI = "content://%s.cim.provider";
|
||||
|
||||
|
||||
public static void remove(Context context, String key) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
resolver.delete(Uri.parse(String.format(CONTENT_URI,context.getPackageName())), key, null);
|
||||
}
|
||||
public static void remove(Context context, String key) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
resolver.delete(Uri.parse(String.format(CONTENT_URI, context.getPackageName())), key, null);
|
||||
}
|
||||
|
||||
public static void putString(Context context, String key, String value) {
|
||||
public static void putString(Context context, String key, String value) {
|
||||
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("value", value);
|
||||
values.put("key", key);
|
||||
resolver.insert(Uri.parse(String.format(CONTENT_URI,context.getPackageName())), values);
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("value", value);
|
||||
values.put("key", key);
|
||||
resolver.insert(Uri.parse(String.format(CONTENT_URI, context.getPackageName())), values);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static String getString(Context context, String key) {
|
||||
String value = null;
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Cursor cursor = resolver.query(Uri.parse(String.format(CONTENT_URI,context.getPackageName())), new String[] { key }, null, null, null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
value = cursor.getString(0);
|
||||
}
|
||||
closeQuietly(cursor);
|
||||
return value;
|
||||
}
|
||||
public static String getString(Context context, String key) {
|
||||
String value = null;
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Cursor cursor = resolver.query(Uri.parse(String.format(CONTENT_URI, context.getPackageName())), new String[]{key}, null, null, null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
value = cursor.getString(0);
|
||||
}
|
||||
closeQuietly(cursor);
|
||||
return value;
|
||||
}
|
||||
|
||||
private static void closeQuietly(Cursor cursor) {
|
||||
try {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
private static void closeQuietly(Cursor cursor) {
|
||||
try {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void putBoolean(Context context, String key, boolean value) {
|
||||
putString(context, key, Boolean.toString(value));
|
||||
}
|
||||
public static void putBoolean(Context context, String key, boolean value) {
|
||||
putString(context, key, Boolean.toString(value));
|
||||
}
|
||||
|
||||
public static boolean getBoolean(Context context, String key) {
|
||||
String value = getString(context, key);
|
||||
return Boolean.parseBoolean(value);
|
||||
}
|
||||
public static boolean getBoolean(Context context, String key) {
|
||||
String value = getString(context, key);
|
||||
return Boolean.parseBoolean(value);
|
||||
}
|
||||
|
||||
public static void putInt(Context context, String key, int value) {
|
||||
putString(context, key, String.valueOf(value));
|
||||
}
|
||||
public static void putInt(Context context, String key, int value) {
|
||||
putString(context, key, String.valueOf(value));
|
||||
}
|
||||
|
||||
public static int getInt(Context context, String key) {
|
||||
String value = getString(context, key);
|
||||
return value == null ? 0 : Integer.parseInt(value);
|
||||
}
|
||||
public static int getInt(Context context, String key) {
|
||||
String value = getString(context, key);
|
||||
return value == null ? 0 : Integer.parseInt(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,43 +29,43 @@ import android.database.MatrixCursor;
|
||||
import android.net.Uri;
|
||||
|
||||
public class CIMCacheProvider extends ContentProvider {
|
||||
static final String MODEL_KEY = "PRIVATE_CIM_CONFIG";
|
||||
static final String MODEL_KEY = "PRIVATE_CIM_CONFIG";
|
||||
|
||||
@Override
|
||||
public int delete(Uri arg0, String key, String[] arg2) {
|
||||
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().remove(key).apply();
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int delete(Uri arg0, String key, String[] arg2) {
|
||||
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().remove(key).apply();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri arg0) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String getType(Uri arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri arg0, ContentValues values) {
|
||||
String key = values.getAsString("key");
|
||||
String value = values.getAsString("value");
|
||||
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().putString(key, value).apply();
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Uri insert(Uri arg0, ContentValues values) {
|
||||
String key = values.getAsString("key");
|
||||
String value = values.getAsString("value");
|
||||
getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).edit().putString(key, value).apply();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri arg0, String[] arg1, String key, String[] arg3, String arg4) {
|
||||
MatrixCursor cursor = new MatrixCursor(new String[] { "value" });
|
||||
String value = getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).getString(arg1[0], null);
|
||||
cursor.addRow(new Object[] { value });
|
||||
return cursor;
|
||||
}
|
||||
@Override
|
||||
public Cursor query(Uri arg0, String[] arg1, String key, String[] arg3, String arg4) {
|
||||
MatrixCursor cursor = new MatrixCursor(new String[]{"value"});
|
||||
String value = getContext().getSharedPreferences(MODEL_KEY, Context.MODE_PRIVATE).getString(arg1[0], null);
|
||||
cursor.addRow(new Object[]{value});
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Process;
|
||||
import com.farsunset.cim.sdk.android.coder.CIMLogger;
|
||||
import com.farsunset.cim.sdk.android.logger.CIMLogger;
|
||||
import com.farsunset.cim.sdk.android.coder.ClientMessageDecoder;
|
||||
import com.farsunset.cim.sdk.android.coder.ClientMessageEncoder;
|
||||
import com.farsunset.cim.sdk.android.constant.CIMConstant;
|
||||
@ -41,368 +41,312 @@ import java.nio.channels.SocketChannel;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
/*
|
||||
* 连接服务端管理,cim核心处理类,管理连接,以及消息处理
|
||||
*
|
||||
* @author 3979434@qq.com
|
||||
*/
|
||||
class CIMConnectorManager{
|
||||
class CIMConnectorManager {
|
||||
|
||||
private static CIMConnectorManager manager;
|
||||
|
||||
private static final int READ_BUFFER_SIZE = 2048;
|
||||
private static final int WRITE_BUFFER_SIZE = 1024;
|
||||
private static CIMConnectorManager manager;
|
||||
|
||||
private static final int READ_IDLE_TIME = 120 * 1000;
|
||||
|
||||
private static final int CONNECT_TIME_OUT = 10 * 1000;
|
||||
private static final int READ_BUFFER_SIZE = 2048;
|
||||
|
||||
private static final int WRITE_BUFFER_SIZE = 1024;
|
||||
|
||||
private static final int READ_IDLE_TIME = 120 * 1000;
|
||||
|
||||
private static final int CONNECT_TIME_OUT = 10 * 1000;
|
||||
|
||||
private static final int CONNECT_ALIVE_TIME_OUT = 150 * 1000;
|
||||
|
||||
|
||||
private static final int CONNECT_ALIVE_TIME_OUT = 150 * 1000;
|
||||
|
||||
private static final AtomicLong LAST_READ_TIME = new AtomicLong(0);
|
||||
|
||||
|
||||
private static final CIMLogger LOGGER = CIMLogger.getLogger();
|
||||
|
||||
|
||||
private static final HandlerThread IDLE_HANDLER_THREAD = new HandlerThread("READ-IDLE", Process.THREAD_PRIORITY_BACKGROUND);
|
||||
|
||||
private Semaphore semaphore = new Semaphore(1, true);
|
||||
|
||||
private volatile SocketChannel socketChannel ;
|
||||
|
||||
private Context context;
|
||||
|
||||
|
||||
private ByteBuffer readBuffer = ByteBuffer.allocate(READ_BUFFER_SIZE);
|
||||
|
||||
private ExecutorService workerExecutor = Executors.newFixedThreadPool(1, r -> new Thread(r,"worker-"));
|
||||
|
||||
private ExecutorService bossExecutor = Executors.newFixedThreadPool(1, r -> new Thread(r,"boss-"));
|
||||
|
||||
private ClientMessageEncoder messageEncoder = new ClientMessageEncoder();
|
||||
private ClientMessageDecoder messageDecoder = new ClientMessageDecoder();
|
||||
|
||||
static {
|
||||
IDLE_HANDLER_THREAD.start();
|
||||
}
|
||||
private CIMConnectorManager(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
public synchronized static CIMConnectorManager getManager(Context context) {
|
||||
|
||||
if (manager == null) {
|
||||
manager = new CIMConnectorManager(context);
|
||||
}
|
||||
|
||||
return manager;
|
||||
|
||||
}
|
||||
private volatile SocketChannel socketChannel;
|
||||
|
||||
public void connect(final String host, final int port) {
|
||||
private final Context context;
|
||||
|
||||
if (!CIMPushManager.isNetworkConnected(context)) {
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECT_FAILED);
|
||||
context.sendBroadcast(intent);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bossExecutor.execute(() -> {
|
||||
|
||||
if (isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.startConnect(host, port);
|
||||
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
|
||||
|
||||
try {
|
||||
|
||||
semaphore.acquire();
|
||||
|
||||
socketChannel = SocketChannel.open();
|
||||
socketChannel.configureBlocking(true);
|
||||
socketChannel.socket().setTcpNoDelay(true);
|
||||
socketChannel.socket().setKeepAlive(true);
|
||||
socketChannel.socket().setReceiveBufferSize(READ_BUFFER_SIZE);
|
||||
socketChannel.socket().setSendBufferSize(WRITE_BUFFER_SIZE);
|
||||
|
||||
socketChannel.socket().connect(new InetSocketAddress(host, port),CONNECT_TIME_OUT);
|
||||
|
||||
semaphore.release();
|
||||
|
||||
handelConnectedEvent();
|
||||
private final ByteBuffer headerBuffer = ByteBuffer.allocate(CIMConstant.DATA_HEADER_LENGTH);
|
||||
|
||||
|
||||
int result = -1;
|
||||
private final ExecutorService workerExecutor = Executors.newFixedThreadPool(1, r -> new Thread(r, "worker-"));
|
||||
|
||||
while((result = socketChannel.read(readBuffer)) > 0) {
|
||||
private final ExecutorService bossExecutor = Executors.newFixedThreadPool(1, r -> new Thread(r, "boss-"));
|
||||
|
||||
if(readBuffer.position() == readBuffer.capacity()) {
|
||||
extendByteBuffer();
|
||||
}
|
||||
private final ClientMessageEncoder messageEncoder = new ClientMessageEncoder();
|
||||
private final ClientMessageDecoder messageDecoder = new ClientMessageDecoder();
|
||||
|
||||
handelSocketReadEvent(result);
|
||||
static {
|
||||
IDLE_HANDLER_THREAD.start();
|
||||
}
|
||||
|
||||
}
|
||||
private CIMConnectorManager(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
handelSocketReadEvent(result);
|
||||
|
||||
}catch(ConnectException | SocketTimeoutException ignore){
|
||||
semaphore.release();
|
||||
handleConnectAbortedEvent();
|
||||
} catch(IOException ignore) {
|
||||
semaphore.release();
|
||||
handelDisconnectedEvent();
|
||||
}catch(InterruptedException ignore) {
|
||||
semaphore.release();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public synchronized static CIMConnectorManager getManager(Context context) {
|
||||
|
||||
if (manager == null) {
|
||||
manager = new CIMConnectorManager(context);
|
||||
}
|
||||
|
||||
return manager;
|
||||
|
||||
}
|
||||
|
||||
public void connect(final String host, final int port) {
|
||||
|
||||
if (!CIMPushManager.isNetworkConnected(context)) {
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECT_FAILED);
|
||||
context.sendBroadcast(intent);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bossExecutor.execute(() -> {
|
||||
|
||||
if (isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.startConnect(host, port);
|
||||
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
|
||||
|
||||
try {
|
||||
|
||||
socketChannel = SocketChannel.open();
|
||||
socketChannel.configureBlocking(true);
|
||||
socketChannel.socket().setTcpNoDelay(true);
|
||||
socketChannel.socket().setKeepAlive(true);
|
||||
socketChannel.socket().setReceiveBufferSize(READ_BUFFER_SIZE);
|
||||
socketChannel.socket().setSendBufferSize(WRITE_BUFFER_SIZE);
|
||||
|
||||
socketChannel.socket().connect(new InetSocketAddress(host, port), CONNECT_TIME_OUT);
|
||||
|
||||
handleConnectedEvent();
|
||||
|
||||
/*
|
||||
*开始读取来自服务端的消息,先读取3个字节的消息头
|
||||
*/
|
||||
while (socketChannel.read(headerBuffer) > 0) {
|
||||
handleSocketReadEvent();
|
||||
}
|
||||
|
||||
/*
|
||||
*read 返回 <= 0的情况,发生了意外需要断开重链
|
||||
*/
|
||||
closeSession();
|
||||
|
||||
} catch (ConnectException | SocketTimeoutException ignore) {
|
||||
handleConnectAbortedEvent();
|
||||
} catch (IOException ignore) {
|
||||
handleDisconnectedEvent();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
|
||||
closeSession();
|
||||
closeSession();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void closeSession() {
|
||||
|
||||
public void closeSession() {
|
||||
|
||||
if(!isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
socketChannel.close();
|
||||
} catch (IOException ignore) {
|
||||
}finally {
|
||||
this.sessionClosed();
|
||||
}
|
||||
}
|
||||
if (!isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return socketChannel != null && socketChannel.isConnected();
|
||||
}
|
||||
|
||||
|
||||
public void send(final Protobufable body) {
|
||||
|
||||
if(!isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
workerExecutor.execute(() -> {
|
||||
int result = 0;
|
||||
try {
|
||||
try {
|
||||
socketChannel.close();
|
||||
} catch (IOException ignore) {
|
||||
} finally {
|
||||
this.sessionClosed();
|
||||
}
|
||||
}
|
||||
|
||||
semaphore.acquire();
|
||||
|
||||
ByteBuffer buffer = messageEncoder.encode(body);
|
||||
while(buffer.hasRemaining()){
|
||||
result += socketChannel.write(buffer);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
result = -1;
|
||||
}finally {
|
||||
|
||||
semaphore.release();
|
||||
|
||||
if(result <= 0) {
|
||||
closeSession();
|
||||
}else {
|
||||
messageSent(body);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void sessionCreated() {
|
||||
LOGGER.sessionCreated(socketChannel);
|
||||
|
||||
LAST_READ_TIME.set(System.currentTimeMillis());
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECT_FINISHED);
|
||||
context.sendBroadcast(intent);
|
||||
|
||||
}
|
||||
|
||||
private void sessionClosed() {
|
||||
|
||||
idleHandler.removeMessages(0);
|
||||
|
||||
LAST_READ_TIME.set(0);
|
||||
|
||||
LOGGER.sessionClosed(socketChannel);
|
||||
|
||||
readBuffer.clear();
|
||||
|
||||
if(readBuffer.capacity() > READ_BUFFER_SIZE) {
|
||||
readBuffer = ByteBuffer.allocate(READ_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED);
|
||||
context.sendBroadcast(intent);
|
||||
|
||||
}
|
||||
|
||||
private void sessionIdle() {
|
||||
|
||||
LOGGER.sessionIdle(socketChannel);
|
||||
|
||||
/*
|
||||
* 用于解决,wifi情况下。偶而路由器与服务器断开连接时,客户端并没及时收到关闭事件 导致这样的情况下当前连接无效也不会重连的问题
|
||||
*/
|
||||
if (System.currentTimeMillis() - LAST_READ_TIME.get() >= CONNECT_ALIVE_TIME_OUT) {
|
||||
closeSession();
|
||||
}
|
||||
}
|
||||
public boolean isConnected() {
|
||||
return socketChannel != null && socketChannel.isConnected();
|
||||
}
|
||||
|
||||
|
||||
private void messageReceived(Object obj) {
|
||||
public void send(final Protobufable body) {
|
||||
|
||||
if (obj instanceof Message) {
|
||||
if (!isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED);
|
||||
intent.putExtra(Message.class.getName(), (Message) obj);
|
||||
context.sendBroadcast(intent);
|
||||
workerExecutor.execute(() -> {
|
||||
int result = 0;
|
||||
try {
|
||||
|
||||
}
|
||||
if (obj instanceof ReplyBody) {
|
||||
ByteBuffer buffer = messageEncoder.encode(body);
|
||||
while (buffer.hasRemaining()) {
|
||||
result += socketChannel.write(buffer);
|
||||
}
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED);
|
||||
intent.putExtra(ReplyBody.class.getName(), (ReplyBody) obj);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
result = -1;
|
||||
} finally {
|
||||
|
||||
|
||||
private void messageSent(Object message) {
|
||||
|
||||
LOGGER.messageSent(socketChannel, message);
|
||||
|
||||
if (message instanceof SentBody) {
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_SEND_FINISHED);
|
||||
intent.putExtra(SentBody.class.getName(), (SentBody) message);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
if (result <= 0) {
|
||||
closeSession();
|
||||
} else {
|
||||
messageSent(body);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void sessionCreated() {
|
||||
LOGGER.sessionCreated(socketChannel);
|
||||
|
||||
LAST_READ_TIME.set(System.currentTimeMillis());
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECT_FINISHED);
|
||||
context.sendBroadcast(intent);
|
||||
|
||||
}
|
||||
|
||||
private void sessionClosed() {
|
||||
|
||||
idleHandler.removeMessages(0);
|
||||
|
||||
LAST_READ_TIME.set(0);
|
||||
|
||||
LOGGER.sessionClosed(socketChannel);
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED);
|
||||
context.sendBroadcast(intent);
|
||||
|
||||
}
|
||||
|
||||
private void sessionIdle() {
|
||||
|
||||
LOGGER.sessionIdle(socketChannel);
|
||||
|
||||
/*
|
||||
* 用于解决,wifi情况下。偶而路由器与服务器断开连接时,客户端并没及时收到关闭事件 导致这样的情况下当前连接无效也不会重连的问题
|
||||
*/
|
||||
if (System.currentTimeMillis() - LAST_READ_TIME.get() >= CONNECT_ALIVE_TIME_OUT) {
|
||||
closeSession();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void messageReceived(Object obj) {
|
||||
|
||||
if (obj instanceof Message) {
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED);
|
||||
intent.putExtra(Message.class.getName(), (Message) obj);
|
||||
context.sendBroadcast(intent);
|
||||
|
||||
}
|
||||
if (obj instanceof ReplyBody) {
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_REPLY_RECEIVED);
|
||||
intent.putExtra(ReplyBody.class.getName(), (ReplyBody) obj);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void messageSent(Object message) {
|
||||
|
||||
LOGGER.messageSent(socketChannel, message);
|
||||
|
||||
if (message instanceof SentBody) {
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_SEND_FINISHED);
|
||||
intent.putExtra(SentBody.class.getName(), (SentBody) message);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
|
||||
private final Handler idleHandler = new Handler(IDLE_HANDLER_THREAD.getLooper()) {
|
||||
@Override
|
||||
public void handleMessage(android.os.Message m) {
|
||||
sessionIdle();
|
||||
}
|
||||
};
|
||||
|
||||
private void handleDisconnectedEvent() {
|
||||
closeSession();
|
||||
}
|
||||
|
||||
private Handler idleHandler = new Handler(IDLE_HANDLER_THREAD.getLooper()) {
|
||||
@Override
|
||||
public void handleMessage(android.os.Message m) {
|
||||
sessionIdle();
|
||||
}
|
||||
};
|
||||
|
||||
private void handelDisconnectedEvent() {
|
||||
closeSession();
|
||||
}
|
||||
|
||||
private void handleConnectAbortedEvent() {
|
||||
|
||||
long interval = CIMConstant.RECONNECT_INTERVAL_TIME - (5 * 1000 - new Random().nextInt(15 * 1000));
|
||||
|
||||
LOGGER.connectFailure(interval);
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECT_FAILED);
|
||||
intent.putExtra("interval", interval);
|
||||
context.sendBroadcast(intent);
|
||||
long interval = CIMConstant.RECONNECT_INTERVAL_TIME - (5 * 1000 - new Random().nextInt(15 * 1000));
|
||||
|
||||
}
|
||||
|
||||
private void handelConnectedEvent() {
|
||||
|
||||
sessionCreated();
|
||||
|
||||
idleHandler.sendEmptyMessageDelayed(0, READ_IDLE_TIME);
|
||||
}
|
||||
|
||||
private void handelSocketReadEvent(int result) {
|
||||
|
||||
if(result == -1) {
|
||||
closeSession();
|
||||
return;
|
||||
}
|
||||
|
||||
markLastReadTime();
|
||||
|
||||
readBuffer.position(0);
|
||||
|
||||
Object message = messageDecoder.doDecode(readBuffer);
|
||||
|
||||
if(message == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.messageReceived(socketChannel,message);
|
||||
LOGGER.connectFailure(interval);
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(context.getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_CONNECT_FAILED);
|
||||
intent.putExtra("interval", interval);
|
||||
context.sendBroadcast(intent);
|
||||
|
||||
}
|
||||
|
||||
private void handleConnectedEvent() {
|
||||
|
||||
sessionCreated();
|
||||
|
||||
idleHandler.sendEmptyMessageDelayed(0, READ_IDLE_TIME);
|
||||
}
|
||||
|
||||
private void handleSocketReadEvent() throws IOException {
|
||||
|
||||
onMessageDecodeFinished(messageDecoder.doDecode(headerBuffer,socketChannel));
|
||||
|
||||
markLastReadTime();
|
||||
|
||||
}
|
||||
|
||||
private void onMessageDecodeFinished(Object message){
|
||||
|
||||
LOGGER.messageReceived(socketChannel, message);
|
||||
|
||||
if (message instanceof HeartbeatRequest) {
|
||||
send(HeartbeatResponse.getInstance());
|
||||
return;
|
||||
}
|
||||
|
||||
this.messageReceived(message);
|
||||
}
|
||||
|
||||
if(isHeartbeatRequest(message)) {
|
||||
|
||||
send(HeartbeatResponse.getInstance());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.messageReceived(message);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void extendByteBuffer() {
|
||||
|
||||
ByteBuffer newBuffer = ByteBuffer.allocate(readBuffer.capacity() + READ_BUFFER_SIZE / 2);
|
||||
readBuffer.position(0);
|
||||
newBuffer.put(readBuffer);
|
||||
|
||||
readBuffer.clear();
|
||||
readBuffer = newBuffer;
|
||||
}
|
||||
|
||||
|
||||
private void markLastReadTime() {
|
||||
|
||||
LAST_READ_TIME.set(System.currentTimeMillis());
|
||||
|
||||
idleHandler.removeMessages(0);
|
||||
|
||||
idleHandler.sendEmptyMessageDelayed(0, READ_IDLE_TIME);
|
||||
|
||||
}
|
||||
LAST_READ_TIME.set(System.currentTimeMillis());
|
||||
|
||||
idleHandler.removeMessages(0);
|
||||
|
||||
private boolean isHeartbeatRequest(Object data) {
|
||||
return data instanceof HeartbeatRequest;
|
||||
}
|
||||
|
||||
idleHandler.sendEmptyMessageDelayed(0, READ_IDLE_TIME);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,189 +31,190 @@ import com.farsunset.cim.sdk.android.model.Message;
|
||||
import com.farsunset.cim.sdk.android.model.ReplyBody;
|
||||
import com.farsunset.cim.sdk.android.model.SentBody;
|
||||
|
||||
/**
|
||||
/*
|
||||
* 消息入口,所有消息都会经过这里
|
||||
*/
|
||||
public abstract class CIMEventBroadcastReceiver extends BroadcastReceiver {
|
||||
|
||||
protected Context context;
|
||||
protected Context context;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
this.context = context;
|
||||
this.context = context;
|
||||
|
||||
String action = intent.getAction();
|
||||
String action = intent.getAction();
|
||||
|
||||
/*
|
||||
* 操作事件广播,用于提高service存活率
|
||||
*/
|
||||
if (Intent.ACTION_USER_PRESENT.equals(action)
|
||||
|| Intent.ACTION_POWER_CONNECTED.equals(action)
|
||||
|| Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
|
||||
startPushService();
|
||||
}
|
||||
|
||||
/*
|
||||
* 设备网络状态变化事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_NETWORK_CHANGED.equals(action)
|
||||
||ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
|
||||
|
||||
onDevicesNetworkChanged();
|
||||
}
|
||||
|
||||
/*
|
||||
* cim断开服务器事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED.equals(action)) {
|
||||
onInnerConnectionClosed();
|
||||
}
|
||||
|
||||
/*
|
||||
* cim连接服务器失败事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_CONNECT_FAILED.equals(action)) {
|
||||
long interval = intent.getLongExtra("interval", CIMConstant.RECONNECT_INTERVAL_TIME);
|
||||
onInnerConnectFailed(interval);
|
||||
}
|
||||
|
||||
/*
|
||||
* cim连接服务器成功事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_CONNECT_FINISHED.equals(action)) {
|
||||
onInnerConnectFinished();
|
||||
}
|
||||
|
||||
/*
|
||||
* 收到推送消息事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED.equals(action)) {
|
||||
onInnerMessageReceived((Message) intent.getSerializableExtra(Message.class.getName()), intent);
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取收到replyBody成功事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_REPLY_RECEIVED.equals(action)) {
|
||||
onReplyReceived((ReplyBody) intent.getSerializableExtra(ReplyBody.class.getName()));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 获取sendBody发送成功事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_SEND_FINISHED.equals(action)) {
|
||||
onSentSucceed((SentBody) intent.getSerializableExtra(SentBody.class.getName()));
|
||||
}
|
||||
|
||||
/*
|
||||
* 重新连接,如果断开的话
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_CONNECTION_RECOVERY.equals(action)) {
|
||||
connect(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void startPushService() {
|
||||
|
||||
Intent intent = new Intent(context, CIMPushService.class);
|
||||
intent.setAction(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
context.startForegroundService(intent);
|
||||
} else {
|
||||
context.startService(intent);
|
||||
/*
|
||||
* 操作事件广播,用于提高service存活率
|
||||
*/
|
||||
if (Intent.ACTION_USER_PRESENT.equals(action)
|
||||
|| Intent.ACTION_POWER_CONNECTED.equals(action)
|
||||
|| Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
|
||||
startPushService();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void onInnerConnectionClosed() {
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
|
||||
/*
|
||||
* 设备网络状态变化事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_NETWORK_CHANGED.equals(action)
|
||||
|| ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
|
||||
|
||||
if (CIMPushManager.isNetworkConnected(context)) {
|
||||
connect(0);
|
||||
}
|
||||
onDevicesNetworkChanged();
|
||||
}
|
||||
|
||||
onConnectionClosed();
|
||||
}
|
||||
/*
|
||||
* cim断开服务器事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_CONNECTION_CLOSED.equals(action)) {
|
||||
onInnerConnectionClosed();
|
||||
}
|
||||
|
||||
private void onInnerConnectFailed(long interval) {
|
||||
/*
|
||||
* cim连接服务器失败事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_CONNECT_FAILED.equals(action)) {
|
||||
long interval = intent.getLongExtra("interval", CIMConstant.RECONNECT_INTERVAL_TIME);
|
||||
onInnerConnectFailed(interval);
|
||||
}
|
||||
|
||||
if (CIMPushManager.isNetworkConnected(context)) {
|
||||
|
||||
onConnectFailed();
|
||||
|
||||
connect(interval);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* cim连接服务器成功事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_CONNECT_FINISHED.equals(action)) {
|
||||
onInnerConnectFinished();
|
||||
}
|
||||
|
||||
private void onInnerConnectFinished() {
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, true);
|
||||
/*
|
||||
* 收到推送消息事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_MESSAGE_RECEIVED.equals(action)) {
|
||||
onInnerMessageReceived((Message) intent.getSerializableExtra(Message.class.getName()), intent);
|
||||
}
|
||||
|
||||
boolean autoBind = CIMPushManager.autoBindAccount(context);
|
||||
onConnectFinished(autoBind);
|
||||
}
|
||||
|
||||
private void onDevicesNetworkChanged() {
|
||||
|
||||
if (CIMPushManager.isNetworkConnected(context)) {
|
||||
connect(0);
|
||||
}
|
||||
|
||||
onNetworkChanged();
|
||||
}
|
||||
|
||||
private void connect(long delay) {
|
||||
Intent serviceIntent = new Intent(context, CIMPushService.class);
|
||||
serviceIntent.putExtra(CIMPushService.KEY_DELAYED_TIME, delay);
|
||||
serviceIntent.setAction(CIMPushManager.ACTION_CREATE_CIM_CONNECTION);
|
||||
CIMPushManager.startService(context,serviceIntent);
|
||||
}
|
||||
|
||||
private void onInnerMessageReceived(Message message, Intent intent) {
|
||||
if (isForceOfflineMessage(message.getAction())) {
|
||||
CIMPushManager.stop(context);
|
||||
}
|
||||
|
||||
onMessageReceived(message, intent);
|
||||
}
|
||||
|
||||
private boolean isForceOfflineMessage(String action) {
|
||||
return CIMConstant.MessageAction.ACTION_999.equals(action);
|
||||
}
|
||||
/*
|
||||
* 获取收到replyBody成功事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_REPLY_RECEIVED.equals(action)) {
|
||||
onReplyReceived((ReplyBody) intent.getSerializableExtra(ReplyBody.class.getName()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 接收消息实现方法
|
||||
* @param message
|
||||
* @param intent
|
||||
*/
|
||||
public abstract void onMessageReceived(Message message, Intent intent);
|
||||
/*
|
||||
* 获取sendBody发送成功事件
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_SEND_FINISHED.equals(action)) {
|
||||
onSentSucceed((SentBody) intent.getSerializableExtra(SentBody.class.getName()));
|
||||
}
|
||||
|
||||
public void onNetworkChanged() {
|
||||
CIMListenerManager.notifyOnNetworkChanged(CIMPushManager.getNetworkInfo(context));
|
||||
}
|
||||
/*
|
||||
* 重新连接,如果断开的话
|
||||
*/
|
||||
if (CIMConstant.IntentAction.ACTION_CONNECTION_RECOVERY.equals(action)) {
|
||||
connect(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void onConnectFinished(boolean hasAutoBind) {
|
||||
CIMListenerManager.notifyOnConnectFinished(hasAutoBind);
|
||||
}
|
||||
private void startPushService() {
|
||||
|
||||
public void onConnectFailed() {
|
||||
CIMListenerManager.notifyOnConnectFailed();
|
||||
}
|
||||
Intent intent = new Intent(context, CIMPushService.class);
|
||||
intent.setAction(CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE);
|
||||
|
||||
public void onConnectionClosed() {
|
||||
CIMListenerManager.notifyOnConnectionClosed();
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
context.startForegroundService(intent);
|
||||
} else {
|
||||
context.startService(intent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void onInnerConnectionClosed() {
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, false);
|
||||
|
||||
if (CIMPushManager.isNetworkConnected(context)) {
|
||||
connect(0);
|
||||
}
|
||||
|
||||
onConnectionClosed();
|
||||
}
|
||||
|
||||
private void onInnerConnectFailed(long interval) {
|
||||
|
||||
if (CIMPushManager.isNetworkConnected(context)) {
|
||||
|
||||
onConnectFailed();
|
||||
|
||||
connect(interval);
|
||||
}
|
||||
}
|
||||
|
||||
private void onInnerConnectFinished() {
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE, true);
|
||||
|
||||
boolean autoBind = CIMPushManager.autoBindAccount(context);
|
||||
onConnectFinished(autoBind);
|
||||
}
|
||||
|
||||
private void onDevicesNetworkChanged() {
|
||||
|
||||
if (CIMPushManager.isNetworkConnected(context)) {
|
||||
connect(0);
|
||||
}
|
||||
|
||||
onNetworkChanged();
|
||||
}
|
||||
|
||||
private void connect(long delay) {
|
||||
Intent serviceIntent = new Intent(context, CIMPushService.class);
|
||||
serviceIntent.putExtra(CIMPushService.KEY_DELAYED_TIME, delay);
|
||||
serviceIntent.setAction(CIMPushManager.ACTION_CREATE_CIM_CONNECTION);
|
||||
CIMPushManager.startService(context, serviceIntent);
|
||||
}
|
||||
|
||||
private void onInnerMessageReceived(Message message, Intent intent) {
|
||||
if (isForceOfflineMessage(message.getAction())) {
|
||||
CIMPushManager.stop(context);
|
||||
}
|
||||
|
||||
onMessageReceived(message, intent);
|
||||
}
|
||||
|
||||
private boolean isForceOfflineMessage(String action) {
|
||||
return CIMConstant.MessageAction.ACTION_999.equals(action);
|
||||
}
|
||||
|
||||
|
||||
public void onReplyReceived(ReplyBody body) {
|
||||
CIMListenerManager.notifyOnReplyReceived(body);
|
||||
}
|
||||
/**
|
||||
* 接收消息实现方法
|
||||
*
|
||||
* @param message
|
||||
* @param intent
|
||||
*/
|
||||
public abstract void onMessageReceived(Message message, Intent intent);
|
||||
|
||||
public void onSentSucceed(SentBody body) {
|
||||
CIMListenerManager.notifyOnSendFinished(body);
|
||||
}
|
||||
public void onNetworkChanged() {
|
||||
CIMListenerManager.notifyOnNetworkChanged(CIMPushManager.getNetworkInfo(context));
|
||||
}
|
||||
|
||||
public void onConnectFinished(boolean hasAutoBind) {
|
||||
CIMListenerManager.notifyOnConnectFinished(hasAutoBind);
|
||||
}
|
||||
|
||||
public void onConnectFailed() {
|
||||
CIMListenerManager.notifyOnConnectFailed();
|
||||
}
|
||||
|
||||
public void onConnectionClosed() {
|
||||
CIMListenerManager.notifyOnConnectionClosed();
|
||||
}
|
||||
|
||||
|
||||
public void onReplyReceived(ReplyBody body) {
|
||||
CIMListenerManager.notifyOnReplyReceived(body);
|
||||
}
|
||||
|
||||
public void onSentSucceed(SentBody body) {
|
||||
CIMListenerManager.notifyOnSendFinished(body);
|
||||
}
|
||||
}
|
||||
|
@ -31,57 +31,55 @@ import com.farsunset.cim.sdk.android.model.SentBody;
|
||||
*/
|
||||
public interface CIMEventListener {
|
||||
|
||||
/**
|
||||
* 当收到服务端推送过来的消息时调用
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
void onMessageReceived(Message message);
|
||||
/**
|
||||
* 当收到服务端推送过来的消息时调用
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
void onMessageReceived(Message message);
|
||||
|
||||
/**
|
||||
* 当调用CIMPushManager.sendRequest()向服务端发送请求,获得相应时调用
|
||||
*
|
||||
* @param body
|
||||
*/
|
||||
void onReplyReceived(ReplyBody body);
|
||||
/**
|
||||
* 当调用CIMPushManager.sendRequest()向服务端发送请求,获得相应时调用
|
||||
*
|
||||
* @param body
|
||||
*/
|
||||
void onReplyReceived(ReplyBody body);
|
||||
|
||||
/**
|
||||
* 当调用CIMPushManager.sendRequest()向服务端发送请求成功时
|
||||
*
|
||||
* @param body
|
||||
*/
|
||||
void onSendFinished(SentBody body);
|
||||
/**
|
||||
* 当调用CIMPushManager.sendRequest()向服务端发送请求成功时
|
||||
*
|
||||
* @param body
|
||||
*/
|
||||
void onSendFinished(SentBody body);
|
||||
|
||||
/**
|
||||
* 当手机网络发生变化时调用
|
||||
*
|
||||
* @param info
|
||||
*/
|
||||
void onNetworkChanged(NetworkInfo info);
|
||||
/**
|
||||
* 当手机网络发生变化时调用
|
||||
*
|
||||
* @param info
|
||||
*/
|
||||
void onNetworkChanged(NetworkInfo info);
|
||||
|
||||
/**
|
||||
* 当连接服务器成功时回调
|
||||
*
|
||||
* @param hasAutoBind
|
||||
* true 已经自动绑定账号到服务器了,不需要再手动调用bindAccount
|
||||
*/
|
||||
void onConnectFinished(boolean hasAutoBind);
|
||||
/**
|
||||
* 当连接服务器成功时回调
|
||||
*
|
||||
* @param hasAutoBind true 已经自动绑定账号到服务器了,不需要再手动调用bindAccount
|
||||
*/
|
||||
void onConnectFinished(boolean hasAutoBind);
|
||||
|
||||
/**
|
||||
* 当断开服务器连接的时候回调
|
||||
*
|
||||
*/
|
||||
void onConnectionClosed();
|
||||
/**
|
||||
* 当断开服务器连接的时候回调
|
||||
*/
|
||||
void onConnectionClosed();
|
||||
|
||||
/**
|
||||
* 当连接服务器失败的时候回调
|
||||
*
|
||||
*/
|
||||
void onConnectFailed();
|
||||
/**
|
||||
* 当连接服务器失败的时候回调
|
||||
*/
|
||||
void onConnectFailed();
|
||||
|
||||
/**
|
||||
* 监听器在容器里面的排序。值越大则越先接收
|
||||
* @return 排序 值越大优先级越高
|
||||
*/
|
||||
int getEventDispatchOrder();
|
||||
/**
|
||||
* 监听器在容器里面的排序。值越大则越先接收
|
||||
*
|
||||
* @return 排序 值越大优先级越高
|
||||
*/
|
||||
int getEventDispatchOrder();
|
||||
}
|
||||
|
@ -37,96 +37,96 @@ import java.util.Iterator;
|
||||
*/
|
||||
public class CIMListenerManager {
|
||||
|
||||
private static ArrayList<CIMEventListener> cimListeners = new ArrayList<CIMEventListener>();
|
||||
private static ReceiveComparator comparator = new ReceiveComparator();
|
||||
private static final ArrayList<CIMEventListener> cimListeners = new ArrayList<CIMEventListener>();
|
||||
private static final ReceiveComparator comparator = new ReceiveComparator();
|
||||
|
||||
private CIMListenerManager(){
|
||||
private CIMListenerManager() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerMessageListener(CIMEventListener listener) {
|
||||
public static void registerMessageListener(CIMEventListener listener) {
|
||||
|
||||
if (!cimListeners.contains(listener)) {
|
||||
cimListeners.add(listener);
|
||||
Collections.sort(cimListeners,comparator);
|
||||
}
|
||||
}
|
||||
if (!cimListeners.contains(listener)) {
|
||||
cimListeners.add(listener);
|
||||
Collections.sort(cimListeners, comparator);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeMessageListener(CIMEventListener listener) {
|
||||
Iterator<CIMEventListener> iterable = cimListeners.iterator();
|
||||
while (iterable.hasNext()){
|
||||
CIMEventListener target = iterable.next();
|
||||
if (listener.getClass() == target.getClass()) {
|
||||
iterable.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void removeMessageListener(CIMEventListener listener) {
|
||||
Iterator<CIMEventListener> iterable = cimListeners.iterator();
|
||||
while (iterable.hasNext()) {
|
||||
CIMEventListener target = iterable.next();
|
||||
if (listener.getClass() == target.getClass()) {
|
||||
iterable.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyOnNetworkChanged(NetworkInfo info) {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onNetworkChanged(info);
|
||||
}
|
||||
}
|
||||
public static void notifyOnNetworkChanged(NetworkInfo info) {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onNetworkChanged(info);
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyOnConnectFinished(boolean hasAutoBind) {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onConnectFinished(hasAutoBind);
|
||||
}
|
||||
}
|
||||
public static void notifyOnConnectFinished(boolean hasAutoBind) {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onConnectFinished(hasAutoBind);
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyOnMessageReceived(Message message) {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onMessageReceived(message);
|
||||
}
|
||||
}
|
||||
public static void notifyOnMessageReceived(Message message) {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onMessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyOnConnectionClosed() {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onConnectionClosed();
|
||||
}
|
||||
}
|
||||
public static void notifyOnConnectionClosed() {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onConnectionClosed();
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyOnConnectFailed() {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onConnectFailed();
|
||||
}
|
||||
}
|
||||
public static void notifyOnConnectFailed() {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onConnectFailed();
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyOnReplyReceived(ReplyBody body) {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onReplyReceived(body);
|
||||
}
|
||||
}
|
||||
public static void notifyOnReplyReceived(ReplyBody body) {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onReplyReceived(body);
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyOnSendFinished(SentBody body) {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onSendFinished(body);
|
||||
}
|
||||
}
|
||||
public static void notifyOnSendFinished(SentBody body) {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onSendFinished(body);
|
||||
}
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
cimListeners.clear();
|
||||
}
|
||||
public static void destroy() {
|
||||
cimListeners.clear();
|
||||
}
|
||||
|
||||
public static void logListenersName() {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
Log.i(CIMEventListener.class.getSimpleName(), "#######" + listener.getClass().getName() + "#######");
|
||||
}
|
||||
}
|
||||
public static void logListenersName() {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
Log.i(CIMEventListener.class.getSimpleName(), "#######" + listener.getClass().getName() + "#######");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息接收activity的接收顺序排序,CIM_RECEIVE_ORDER倒序
|
||||
*/
|
||||
private static class ReceiveComparator implements Comparator<CIMEventListener> {
|
||||
/**
|
||||
* 消息接收activity的接收顺序排序,CIM_RECEIVE_ORDER倒序
|
||||
*/
|
||||
private static class ReceiveComparator implements Comparator<CIMEventListener> {
|
||||
|
||||
@Override
|
||||
public int compare(CIMEventListener arg1, CIMEventListener arg2) {
|
||||
@Override
|
||||
public int compare(CIMEventListener arg1, CIMEventListener arg2) {
|
||||
|
||||
int order1 = arg1.getEventDispatchOrder();
|
||||
int order2 = arg2.getEventDispatchOrder();
|
||||
return Integer.compare(order2,order1);
|
||||
}
|
||||
int order1 = arg1.getEventDispatchOrder();
|
||||
int order2 = arg2.getEventDispatchOrder();
|
||||
return Integer.compare(order2, order1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import com.farsunset.cim.sdk.android.coder.CIMLogger;
|
||||
import com.farsunset.cim.sdk.android.logger.CIMLogger;
|
||||
import com.farsunset.cim.sdk.android.constant.CIMConstant;
|
||||
import com.farsunset.cim.sdk.android.model.SentBody;
|
||||
|
||||
@ -40,208 +40,211 @@ import java.util.UUID;
|
||||
*/
|
||||
public class CIMPushManager {
|
||||
|
||||
protected static String ACTION_ACTIVATE_PUSH_SERVICE = "ACTION_ACTIVATE_PUSH_SERVICE";
|
||||
protected static final String ACTION_ACTIVATE_PUSH_SERVICE = "ACTION_ACTIVATE_PUSH_SERVICE";
|
||||
|
||||
protected static String ACTION_CREATE_CIM_CONNECTION = "ACTION_CREATE_CIM_CONNECTION";
|
||||
protected static final String ACTION_CREATE_CIM_CONNECTION = "ACTION_CREATE_CIM_CONNECTION";
|
||||
|
||||
protected static String ACTION_SEND_REQUEST_BODY = "ACTION_SEND_REQUEST_BODY";
|
||||
protected static final String ACTION_SEND_REQUEST_BODY = "ACTION_SEND_REQUEST_BODY";
|
||||
|
||||
protected static String ACTION_CLOSE_CIM_CONNECTION = "ACTION_CLOSE_CIM_CONNECTION";
|
||||
protected static final String ACTION_CLOSE_CIM_CONNECTION = "ACTION_CLOSE_CIM_CONNECTION";
|
||||
|
||||
protected static String ACTION_SET_LOGGER_EATABLE = "ACTION_SET_LOGGER_EATABLE";
|
||||
protected static final String ACTION_DESTROY_CIM_SERVICE = "ACTION_DESTROY_CIM_SERVICE";
|
||||
|
||||
protected static String KEY_SEND_BODY = "KEY_SEND_BODY";
|
||||
protected static final String ACTION_SET_LOGGER_EATABLE = "ACTION_SET_LOGGER_EATABLE";
|
||||
|
||||
/**
|
||||
* 初始化,连接服务端,在程序启动页或者 在Application里调用
|
||||
*/
|
||||
public static void connect(Context context, String host, int port) {
|
||||
protected static final String KEY_SEND_BODY = "KEY_SEND_BODY";
|
||||
|
||||
if(TextUtils.isEmpty(host) || port == 0) {
|
||||
CIMLogger.getLogger().invalidHostPort(host, port);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化,连接服务端,在程序启动页或者 在Application里调用
|
||||
*/
|
||||
public static void connect(Context context, String host, int port) {
|
||||
|
||||
CIMCacheManager.putString(context, CIMCacheManager.KEY_CIM_SERVER_HOST, host);
|
||||
CIMCacheManager.putInt(context, CIMCacheManager.KEY_CIM_SERVER_PORT, port);
|
||||
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED, false);
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, false);
|
||||
|
||||
CIMCacheManager.remove(context, CIMCacheManager.KEY_ACCOUNT);
|
||||
|
||||
|
||||
Intent serviceIntent = new Intent(context, CIMPushService.class);
|
||||
serviceIntent.setAction(ACTION_CREATE_CIM_CONNECTION);
|
||||
startService(context,serviceIntent);
|
||||
|
||||
}
|
||||
|
||||
public static void setLoggerEnable(Context context,boolean enable) {
|
||||
Intent serviceIntent = new Intent(context, CIMPushService.class);
|
||||
serviceIntent.putExtra(CIMPushService.KEY_LOGGER_ENABLE, enable);
|
||||
serviceIntent.setAction(ACTION_SET_LOGGER_EATABLE);
|
||||
startService(context,serviceIntent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置一个账号登录到服务端
|
||||
*/
|
||||
public static void bindAccount(Context context, String account) {
|
||||
|
||||
if (isDestroyed(context) || account == null || account.trim().length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendBindRequest(context, account);
|
||||
|
||||
}
|
||||
|
||||
private static void sendBindRequest(Context context, String account) {
|
||||
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, false);
|
||||
CIMCacheManager.putString(context, CIMCacheManager.KEY_ACCOUNT, account);
|
||||
|
||||
|
||||
SentBody sent = new SentBody();
|
||||
sent.setKey(CIMConstant.RequestKey.CLIENT_BIND);
|
||||
sent.put("account", account);
|
||||
sent.put("deviceId", getDeviceId(context));
|
||||
sent.put("channel", "android");
|
||||
sent.put("device", Build.MODEL);
|
||||
sent.put("appVersion", getVersionName(context));
|
||||
sent.put("osVersion", Build.VERSION.RELEASE);
|
||||
sent.put("packageName", context.getPackageName());
|
||||
sent.setTimestamp(System.currentTimeMillis());
|
||||
sendRequest(context, sent);
|
||||
}
|
||||
|
||||
protected static boolean autoBindAccount(Context context) {
|
||||
|
||||
String account = CIMCacheManager.getString(context, CIMCacheManager.KEY_ACCOUNT);
|
||||
if (account == null || account.trim().length() == 0 || isDestroyed(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sendBindRequest(context, account);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送一个CIM请求
|
||||
*/
|
||||
public static void sendRequest(Context context, SentBody body) {
|
||||
|
||||
if (isDestroyed(context) || isStopped(context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Intent serviceIntent = new Intent(context, CIMPushService.class);
|
||||
serviceIntent.putExtra(KEY_SEND_BODY, body);
|
||||
serviceIntent.setAction(ACTION_SEND_REQUEST_BODY);
|
||||
startService(context,serviceIntent);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止接受推送,将会退出当前账号登录,端口与服务端的连接
|
||||
*/
|
||||
public static void stop(Context context) {
|
||||
|
||||
if (isDestroyed(context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, true);
|
||||
|
||||
Intent serviceIntent = new Intent(context, CIMPushService.class);
|
||||
serviceIntent.setAction(ACTION_CLOSE_CIM_CONNECTION);
|
||||
startService(context,serviceIntent);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 完全销毁CIM,一般用于完全退出程序,调用resume将不能恢复
|
||||
*/
|
||||
public static void destroy(Context context) {
|
||||
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED, true);
|
||||
CIMCacheManager.putString(context, CIMCacheManager.KEY_ACCOUNT, null);
|
||||
|
||||
context.stopService(new Intent(context, CIMPushService.class));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新恢复接收推送,重新连接服务端,并登录当前账号
|
||||
*/
|
||||
public static void resume(Context context) {
|
||||
|
||||
if (isDestroyed(context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
autoBindAccount(context);
|
||||
}
|
||||
|
||||
public static boolean isDestroyed(Context context) {
|
||||
return CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
}
|
||||
|
||||
public static boolean isStopped(Context context) {
|
||||
return CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_MANUAL_STOP);
|
||||
}
|
||||
|
||||
public static boolean isConnected(Context context) {
|
||||
return CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE);
|
||||
}
|
||||
|
||||
public static boolean isNetworkConnected(Context context) {
|
||||
NetworkInfo networkInfo = getNetworkInfo(context);
|
||||
return networkInfo != null && networkInfo.isConnected();
|
||||
}
|
||||
|
||||
public static NetworkInfo getNetworkInfo(Context context) {
|
||||
return ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
|
||||
}
|
||||
|
||||
|
||||
public static void startService(Context context,Intent intent) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
context.startForegroundService(intent);
|
||||
} else {
|
||||
context.startService(intent);
|
||||
if (TextUtils.isEmpty(host) || port == 0) {
|
||||
CIMLogger.getLogger().invalidHostPort(host, port);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static String getVersionName(Context context) {
|
||||
|
||||
try {
|
||||
PackageInfo mPackageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
||||
return mPackageInfo.versionName;
|
||||
} catch (NameNotFoundException ignore) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getDeviceId(Context context){
|
||||
CIMCacheManager.putString(context, CIMCacheManager.KEY_CIM_SERVER_HOST, host);
|
||||
CIMCacheManager.putInt(context, CIMCacheManager.KEY_CIM_SERVER_PORT, port);
|
||||
|
||||
String currDeviceId = CIMCacheManager.getString(context, CIMCacheManager.KEY_DEVICE_ID);
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED, false);
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, false);
|
||||
|
||||
if (!TextUtils.isEmpty(currDeviceId)) {
|
||||
return currDeviceId;
|
||||
}
|
||||
CIMCacheManager.remove(context, CIMCacheManager.KEY_ACCOUNT);
|
||||
|
||||
String deviceId = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
|
||||
|
||||
CIMCacheManager.putString(context, CIMCacheManager.KEY_DEVICE_ID,deviceId);
|
||||
Intent serviceIntent = new Intent(context, CIMPushService.class);
|
||||
serviceIntent.setAction(ACTION_CREATE_CIM_CONNECTION);
|
||||
startService(context, serviceIntent);
|
||||
|
||||
return deviceId;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setLoggerEnable(Context context, boolean enable) {
|
||||
Intent serviceIntent = new Intent(context, CIMPushService.class);
|
||||
serviceIntent.putExtra(CIMPushService.KEY_LOGGER_ENABLE, enable);
|
||||
serviceIntent.setAction(ACTION_SET_LOGGER_EATABLE);
|
||||
startService(context, serviceIntent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置一个账号登录到服务端
|
||||
*/
|
||||
public static void bindAccount(Context context, String account) {
|
||||
|
||||
if (isDestroyed(context) || account == null || account.trim().length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendBindRequest(context, account);
|
||||
|
||||
}
|
||||
|
||||
private static void sendBindRequest(Context context, String account) {
|
||||
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, false);
|
||||
CIMCacheManager.putString(context, CIMCacheManager.KEY_ACCOUNT, account);
|
||||
|
||||
|
||||
SentBody sent = new SentBody();
|
||||
sent.setKey(CIMConstant.RequestKey.CLIENT_BIND);
|
||||
sent.put("account", account);
|
||||
sent.put("deviceId", getDeviceId(context));
|
||||
sent.put("channel", "android");
|
||||
sent.put("device", Build.MODEL);
|
||||
sent.put("appVersion", getVersionName(context));
|
||||
sent.put("osVersion", Build.VERSION.RELEASE);
|
||||
sent.put("packageName", context.getPackageName());
|
||||
sent.setTimestamp(System.currentTimeMillis());
|
||||
sendRequest(context, sent);
|
||||
}
|
||||
|
||||
protected static boolean autoBindAccount(Context context) {
|
||||
|
||||
String account = CIMCacheManager.getString(context, CIMCacheManager.KEY_ACCOUNT);
|
||||
if (account == null || account.trim().length() == 0 || isDestroyed(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sendBindRequest(context, account);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送一个CIM请求
|
||||
*/
|
||||
public static void sendRequest(Context context, SentBody body) {
|
||||
|
||||
if (isDestroyed(context) || isStopped(context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Intent serviceIntent = new Intent(context, CIMPushService.class);
|
||||
serviceIntent.putExtra(KEY_SEND_BODY, body);
|
||||
serviceIntent.setAction(ACTION_SEND_REQUEST_BODY);
|
||||
startService(context, serviceIntent);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止接受推送,将会退出当前账号登录,端口与服务端的连接
|
||||
*/
|
||||
public static void stop(Context context) {
|
||||
|
||||
if (isDestroyed(context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_MANUAL_STOP, true);
|
||||
|
||||
Intent serviceIntent = new Intent(context, CIMPushService.class);
|
||||
serviceIntent.setAction(ACTION_CLOSE_CIM_CONNECTION);
|
||||
startService(context, serviceIntent);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 完全销毁CIM,一般用于完全退出程序,调用resume将不能恢复
|
||||
*/
|
||||
public static void destroy(Context context) {
|
||||
|
||||
CIMCacheManager.putBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED, true);
|
||||
CIMCacheManager.putString(context, CIMCacheManager.KEY_ACCOUNT, null);
|
||||
|
||||
Intent serviceIntent = new Intent(context, CIMPushService.class);
|
||||
serviceIntent.setAction(ACTION_DESTROY_CIM_SERVICE);
|
||||
startService(context, serviceIntent);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新恢复接收推送,重新连接服务端,并登录当前账号
|
||||
*/
|
||||
public static void resume(Context context) {
|
||||
|
||||
if (isDestroyed(context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
autoBindAccount(context);
|
||||
}
|
||||
|
||||
public static boolean isDestroyed(Context context) {
|
||||
return CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
}
|
||||
|
||||
public static boolean isStopped(Context context) {
|
||||
return CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_MANUAL_STOP);
|
||||
}
|
||||
|
||||
public static boolean isConnected(Context context) {
|
||||
return CIMCacheManager.getBoolean(context, CIMCacheManager.KEY_CIM_CONNECTION_STATE);
|
||||
}
|
||||
|
||||
public static boolean isNetworkConnected(Context context) {
|
||||
NetworkInfo networkInfo = getNetworkInfo(context);
|
||||
return networkInfo != null && networkInfo.isConnected();
|
||||
}
|
||||
|
||||
public static NetworkInfo getNetworkInfo(Context context) {
|
||||
return ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
|
||||
}
|
||||
|
||||
|
||||
public static void startService(Context context, Intent intent) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
context.startForegroundService(intent);
|
||||
} else {
|
||||
context.startService(intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String getVersionName(Context context) {
|
||||
|
||||
try {
|
||||
PackageInfo mPackageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
||||
return mPackageInfo.versionName;
|
||||
} catch (NameNotFoundException ignore) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getDeviceId(Context context) {
|
||||
|
||||
String currDeviceId = CIMCacheManager.getString(context, CIMCacheManager.KEY_DEVICE_ID);
|
||||
|
||||
if (!TextUtils.isEmpty(currDeviceId)) {
|
||||
return currDeviceId;
|
||||
}
|
||||
|
||||
String deviceId = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
|
||||
|
||||
CIMCacheManager.putString(context, CIMCacheManager.KEY_DEVICE_ID, deviceId);
|
||||
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,199 +35,211 @@ import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import com.farsunset.cim.sdk.android.coder.CIMLogger;
|
||||
import com.farsunset.cim.sdk.android.logger.CIMLogger;
|
||||
import com.farsunset.cim.sdk.android.constant.CIMConstant;
|
||||
import com.farsunset.cim.sdk.android.model.SentBody;
|
||||
|
||||
/**
|
||||
* 与服务端连接服务
|
||||
*
|
||||
* @author 3979434
|
||||
*
|
||||
* @author 3979434
|
||||
*/
|
||||
public class CIMPushService extends Service {
|
||||
public final static String KEY_DELAYED_TIME = "KEY_DELAYED_TIME";
|
||||
public final static String KEY_LOGGER_ENABLE = "KEY_LOGGER_ENABLE";
|
||||
public class CIMPushService extends Service {
|
||||
public final static String KEY_DELAYED_TIME = "KEY_DELAYED_TIME";
|
||||
public final static String KEY_LOGGER_ENABLE = "KEY_LOGGER_ENABLE";
|
||||
|
||||
private final static int NOTIFICATION_ID = Integer.MAX_VALUE;
|
||||
|
||||
private CIMConnectorManager manager;
|
||||
private KeepAliveBroadcastReceiver keepAliveReceiver;
|
||||
private final static int NOTIFICATION_ID = Integer.MAX_VALUE;
|
||||
|
||||
private CIMConnectorManager manager;
|
||||
private KeepAliveBroadcastReceiver keepAliveReceiver;
|
||||
private ConnectivityManager connectivityManager;
|
||||
@Override
|
||||
public void onCreate() {
|
||||
manager = CIMConnectorManager.getManager(this.getApplicationContext());
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
manager = CIMConnectorManager.getManager(this.getApplicationContext());
|
||||
|
||||
keepAliveReceiver = new KeepAliveBroadcastReceiver();
|
||||
registerReceiver(keepAliveReceiver, keepAliveReceiver.getIntentFilter());
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
|
||||
connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
connectivityManager.registerDefaultNetworkCallback(networkCallback);
|
||||
keepAliveReceiver = new KeepAliveBroadcastReceiver();
|
||||
registerReceiver(keepAliveReceiver, keepAliveReceiver.getIntentFilter());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
|
||||
@Override
|
||||
public void onAvailable(Network network) {
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_NETWORK_CHANGED);
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
@Override
|
||||
public void onUnavailable() {
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_NETWORK_CHANGED);
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
|
||||
};
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
|
||||
Handler connectHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(android.os.Message message) {
|
||||
connect();
|
||||
}
|
||||
};
|
||||
connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
Handler notificationHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(android.os.Message message) {
|
||||
stopForeground(true);
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
connectivityManager.registerDefaultNetworkCallback(networkCallback);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
NotificationChannel channel = new NotificationChannel(getClass().getSimpleName(),getClass().getSimpleName(), NotificationManager.IMPORTANCE_LOW);
|
||||
channel.enableLights(false);
|
||||
channel.enableVibration(false);
|
||||
channel.setSound(null, null);
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
Notification notification = new Notification.Builder(this, channel.getId())
|
||||
.setContentTitle("Push service")
|
||||
.setContentText("Push service is running")
|
||||
.build();
|
||||
startForeground(NOTIFICATION_ID,notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String action = intent == null ? CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE : intent.getAction();
|
||||
final ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
|
||||
@Override
|
||||
public void onAvailable(Network network) {
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_NETWORK_CHANGED);
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
|
||||
if (CIMPushManager.ACTION_CREATE_CIM_CONNECTION.equals(action)) {
|
||||
connect(intent.getLongExtra(KEY_DELAYED_TIME, 0));
|
||||
}
|
||||
@Override
|
||||
public void onUnavailable() {
|
||||
Intent intent = new Intent();
|
||||
intent.setPackage(getPackageName());
|
||||
intent.setAction(CIMConstant.IntentAction.ACTION_NETWORK_CHANGED);
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
|
||||
if (CIMPushManager.ACTION_SEND_REQUEST_BODY.equals(action)) {
|
||||
manager.send((SentBody) intent.getSerializableExtra(CIMPushManager.KEY_SEND_BODY));
|
||||
}
|
||||
};
|
||||
|
||||
if (CIMPushManager.ACTION_CLOSE_CIM_CONNECTION.equals(action)) {
|
||||
manager.closeSession();
|
||||
}
|
||||
final Handler connectHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(android.os.Message message) {
|
||||
connect();
|
||||
}
|
||||
};
|
||||
|
||||
if (CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE.equals(action)) {
|
||||
handleKeepAlive();
|
||||
}
|
||||
final Handler notificationHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(android.os.Message message) {
|
||||
stopForeground(true);
|
||||
}
|
||||
};
|
||||
|
||||
if (CIMPushManager.ACTION_SET_LOGGER_EATABLE.equals(action)) {
|
||||
boolean enable = intent.getBooleanExtra(KEY_LOGGER_ENABLE, true);
|
||||
CIMLogger.getLogger().debugMode(enable);
|
||||
}
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
notificationHandler.sendEmptyMessageDelayed(0, 1000);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
NotificationChannel channel = new NotificationChannel(getClass().getSimpleName(), getClass().getSimpleName(), NotificationManager.IMPORTANCE_LOW);
|
||||
channel.enableLights(false);
|
||||
channel.enableVibration(false);
|
||||
channel.setSound(null, null);
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
Notification notification = new Notification.Builder(this, channel.getId())
|
||||
.setContentTitle("Push service")
|
||||
.setContentText("Push service is running")
|
||||
.build();
|
||||
startForeground(NOTIFICATION_ID, notification);
|
||||
}
|
||||
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
String action = intent == null ? CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE : intent.getAction();
|
||||
|
||||
private void connect(long delayMillis) {
|
||||
if (CIMPushManager.ACTION_CREATE_CIM_CONNECTION.equals(action)) {
|
||||
connect(intent.getLongExtra(KEY_DELAYED_TIME, 0));
|
||||
}
|
||||
|
||||
if(delayMillis <= 0) {
|
||||
connect();
|
||||
return;
|
||||
}
|
||||
|
||||
connectHandler.sendEmptyMessageDelayed(0, delayMillis);
|
||||
if (CIMPushManager.ACTION_SEND_REQUEST_BODY.equals(action)) {
|
||||
manager.send((SentBody) intent.getSerializableExtra(CIMPushManager.KEY_SEND_BODY));
|
||||
}
|
||||
|
||||
}
|
||||
if (CIMPushManager.ACTION_CLOSE_CIM_CONNECTION.equals(action)) {
|
||||
manager.closeSession();
|
||||
}
|
||||
|
||||
private void connect() {
|
||||
if (CIMPushManager.ACTION_ACTIVATE_PUSH_SERVICE.equals(action)) {
|
||||
handleKeepAlive();
|
||||
}
|
||||
|
||||
if(CIMPushManager.isDestroyed(this) || CIMPushManager.isStopped(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String host = CIMCacheManager.getString(this, CIMCacheManager.KEY_CIM_SERVER_HOST);
|
||||
int port = CIMCacheManager.getInt(this, CIMCacheManager.KEY_CIM_SERVER_PORT);
|
||||
|
||||
if(host == null || host.trim().length() == 0 || port <= 0) {
|
||||
Log.e(this.getClass().getSimpleName(), "Invalid hostname or port. host:" + host + " port:" + port);
|
||||
return;
|
||||
}
|
||||
|
||||
manager.connect(host, port);
|
||||
if (CIMPushManager.ACTION_SET_LOGGER_EATABLE.equals(action)) {
|
||||
boolean enable = intent.getBooleanExtra(KEY_LOGGER_ENABLE, true);
|
||||
CIMLogger.getLogger().debugMode(enable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void handleKeepAlive() {
|
||||
|
||||
if (manager.isConnected()) {
|
||||
CIMLogger.getLogger().connectState(true);
|
||||
return;
|
||||
}
|
||||
|
||||
connect();
|
||||
|
||||
}
|
||||
if (CIMPushManager.ACTION_DESTROY_CIM_SERVICE.equals(action)) {
|
||||
manager.destroy();
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent arg0) {
|
||||
return null;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
notificationHandler.sendEmptyMessageDelayed(0, 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
manager.destroy();
|
||||
connectHandler.removeMessages(0);
|
||||
notificationHandler.removeMessages(0);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
unregisterReceiver(keepAliveReceiver);
|
||||
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
connectivityManager.unregisterNetworkCallback(networkCallback);
|
||||
}
|
||||
}
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
|
||||
public class KeepAliveBroadcastReceiver extends BroadcastReceiver {
|
||||
private void connect(long delayMillis) {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context arg0, Intent arg1) {
|
||||
handleKeepAlive();
|
||||
}
|
||||
if (delayMillis <= 0) {
|
||||
connect();
|
||||
return;
|
||||
}
|
||||
|
||||
public IntentFilter getIntentFilter() {
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
|
||||
intentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
|
||||
intentFilter.addAction(Intent.ACTION_USER_PRESENT);
|
||||
return intentFilter;
|
||||
}
|
||||
connectHandler.sendEmptyMessageDelayed(0, delayMillis);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void connect() {
|
||||
|
||||
if (CIMPushManager.isDestroyed(this) || CIMPushManager.isStopped(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String host = CIMCacheManager.getString(this, CIMCacheManager.KEY_CIM_SERVER_HOST);
|
||||
int port = CIMCacheManager.getInt(this, CIMCacheManager.KEY_CIM_SERVER_PORT);
|
||||
|
||||
if (host == null || host.trim().length() == 0 || port <= 0) {
|
||||
Log.e(this.getClass().getSimpleName(), "Invalid hostname or port. host:" + host + " port:" + port);
|
||||
return;
|
||||
}
|
||||
|
||||
manager.connect(host, port);
|
||||
|
||||
}
|
||||
|
||||
private void handleKeepAlive() {
|
||||
|
||||
if (manager.isConnected()) {
|
||||
CIMLogger.getLogger().connectState(true,CIMPushManager.isStopped(this),CIMPushManager.isDestroyed(this));
|
||||
return;
|
||||
}
|
||||
|
||||
connect();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void release() {
|
||||
connectHandler.removeMessages(0);
|
||||
notificationHandler.removeMessages(0);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
unregisterReceiver(keepAliveReceiver);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
connectivityManager.unregisterNetworkCallback(networkCallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
release();
|
||||
}
|
||||
|
||||
public class KeepAliveBroadcastReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context arg0, Intent arg1) {
|
||||
handleKeepAlive();
|
||||
}
|
||||
|
||||
public IntentFilter getIntentFilter() {
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
|
||||
intentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
|
||||
intentFilter.addAction(Intent.ACTION_USER_PRESENT);
|
||||
return intentFilter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************************
|
||||
* *
|
||||
* Website : http://www.farsunset.com *
|
||||
* *
|
||||
***************************************************************************************
|
||||
*/
|
||||
package com.farsunset.cim.sdk.android.coder;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
|
||||
/**
|
||||
* 日志打印,添加session 的id和ip address
|
||||
*/
|
||||
public class CIMLogger {
|
||||
private final static String TAG = "CIM";
|
||||
private boolean debug = true;
|
||||
|
||||
public static CIMLogger getLogger() {
|
||||
return LoggerHolder.logger;
|
||||
}
|
||||
|
||||
private CIMLogger() {
|
||||
|
||||
}
|
||||
|
||||
private static class LoggerHolder{
|
||||
private static CIMLogger logger = new CIMLogger();
|
||||
}
|
||||
|
||||
public void debugMode(boolean mode) {
|
||||
debug = mode;
|
||||
}
|
||||
|
||||
public void messageReceived(SocketChannel session, Object message) {
|
||||
if(debug) {
|
||||
Log.i(TAG,String.format("[RECEIVED]" + getSessionInfo(session) + "\n%s", message));
|
||||
}
|
||||
}
|
||||
|
||||
public void messageSent(SocketChannel session, Object message) {
|
||||
if(debug) {
|
||||
Log.i(TAG,String.format("[ SENT ]" + getSessionInfo(session) + "\n%s", message));
|
||||
}
|
||||
}
|
||||
|
||||
public void sessionCreated( SocketChannel session) {
|
||||
if(debug) {
|
||||
Log.i(TAG,"[ OPENED ]" + getSessionInfo(session));
|
||||
}
|
||||
}
|
||||
|
||||
public void sessionIdle( SocketChannel session) {
|
||||
if(debug) {
|
||||
Log.d(TAG,"[ IDLE ]" + getSessionInfo(session));
|
||||
}
|
||||
}
|
||||
|
||||
public void sessionClosed( SocketChannel session) {
|
||||
if(debug) {
|
||||
Log.w(TAG,"[ CLOSED ] ID = " + session.hashCode());
|
||||
}
|
||||
}
|
||||
|
||||
public void connectFailure(long interval) {
|
||||
if(debug) {
|
||||
Log.d(TAG,"CONNECT FAILURE, TRY RECONNECT AFTER " + interval +"ms");
|
||||
}
|
||||
}
|
||||
|
||||
public void startConnect(String host , int port) {
|
||||
if(debug) {
|
||||
Log.i(TAG,"START CONNECT REMOTE HOST:" + host + " PORT:" + port);
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidHostPort(String host , int port) {
|
||||
if(debug) {
|
||||
Log.d(TAG,"INVALID SOCKET ADDRESS -> HOST:" + host + " PORT:" + port);
|
||||
}
|
||||
}
|
||||
|
||||
public void connectState(boolean isConnected) {
|
||||
if(debug) {
|
||||
Log.d(TAG,"CONNECTED:" + isConnected);
|
||||
}
|
||||
}
|
||||
|
||||
public void connectState(boolean isConnected,boolean isManualStop,boolean isDestroyed) {
|
||||
if(debug) {
|
||||
Log.d(TAG,"CONNECTED:" + isConnected + " STOPPED:"+isManualStop+ " DESTROYED:"+isDestroyed);
|
||||
}
|
||||
}
|
||||
private String getSessionInfo(SocketChannel session) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (session == null) {
|
||||
return "";
|
||||
}
|
||||
builder.append(" [");
|
||||
builder.append("id:").append(session.hashCode());
|
||||
|
||||
try {
|
||||
if (session.socket().getLocalAddress() != null) {
|
||||
builder.append(" L:").append(session.socket().getLocalAddress()).append(":").append(session.socket().getLocalPort());
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
if (session.socket().getRemoteSocketAddress() != null) {
|
||||
builder.append(" R:").append(session.socket().getRemoteSocketAddress().toString());
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -28,98 +28,86 @@ import com.farsunset.cim.sdk.android.model.Message;
|
||||
import com.farsunset.cim.sdk.android.model.ReplyBody;
|
||||
import com.farsunset.cim.sdk.android.model.proto.MessageProto;
|
||||
import com.farsunset.cim.sdk.android.model.proto.ReplyBodyProto;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
/**
|
||||
* 客户端消息解码
|
||||
*/
|
||||
public class ClientMessageDecoder {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param headerBuffer 读取到的消息头
|
||||
* @param socketChannel
|
||||
* @return
|
||||
*/
|
||||
public Object doDecode(ByteBuffer headerBuffer , SocketChannel socketChannel) throws IOException {
|
||||
|
||||
public Object doDecode(ByteBuffer buffer) {
|
||||
|
||||
/*
|
||||
* 消息头3位
|
||||
*/
|
||||
if (buffer.remaining() < CIMConstant.DATA_HEADER_LENGTH) {
|
||||
return null;
|
||||
}
|
||||
headerBuffer.position(0);
|
||||
|
||||
buffer.mark();
|
||||
byte type = headerBuffer.get();
|
||||
byte lv = headerBuffer.get();
|
||||
byte hv = headerBuffer.get();
|
||||
|
||||
byte type = buffer.get();
|
||||
headerBuffer.clear();
|
||||
|
||||
byte lv = buffer.get();
|
||||
byte hv = buffer.get();
|
||||
/*
|
||||
* 先通过消息头拿到消息的长度,然后进行定长读取
|
||||
* 解决消息的断包和粘包情况
|
||||
*/
|
||||
|
||||
int length = getContentLength(lv, hv);
|
||||
int dataLength = getContentLength(lv, hv);
|
||||
|
||||
/*
|
||||
*如果消息体没有接收完整,则重置读取,等待下一次重新读取
|
||||
*/
|
||||
if (length > buffer.remaining()) {
|
||||
buffer.reset();
|
||||
return null;
|
||||
}
|
||||
ByteBuffer bodyBuffer = ByteBuffer.allocate(dataLength);
|
||||
|
||||
byte[] dataBytes = new byte[length];
|
||||
buffer.get(dataBytes, 0, length);
|
||||
/*
|
||||
* 如果读取的消息长度不够,则进行等待后续消息到来
|
||||
* 当读取的消息长度(bodyBuffer.position() == dataLength)时意味着一个完整的消息已经接收完成
|
||||
*/
|
||||
do {
|
||||
socketChannel.read(bodyBuffer);
|
||||
} while (bodyBuffer.position() != dataLength);
|
||||
|
||||
buffer.position(0);
|
||||
|
||||
try {
|
||||
return mappingMessageObject(dataBytes, type);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Object mappingMessageObject(byte[] bytes, byte type) throws InvalidProtocolBufferException {
|
||||
/*
|
||||
消息读取完成后,通过type来解析成对应的消息体
|
||||
*/
|
||||
if (CIMConstant.ProtobufType.S_H_RQ == type) {
|
||||
return HeartbeatRequest.getInstance();
|
||||
}
|
||||
|
||||
if (CIMConstant.ProtobufType.S_H_RQ == type) {
|
||||
return HeartbeatRequest.getInstance();
|
||||
}
|
||||
if (CIMConstant.ProtobufType.REPLY_BODY == type) {
|
||||
ReplyBodyProto.Model bodyProto = ReplyBodyProto.Model.parseFrom(bodyBuffer.array());
|
||||
ReplyBody body = new ReplyBody();
|
||||
body.setKey(bodyProto.getKey());
|
||||
body.setTimestamp(bodyProto.getTimestamp());
|
||||
body.putAll(bodyProto.getDataMap());
|
||||
body.setCode(bodyProto.getCode());
|
||||
body.setMessage(bodyProto.getMessage());
|
||||
return body;
|
||||
}
|
||||
|
||||
if (CIMConstant.ProtobufType.REPLY_BODY == type) {
|
||||
ReplyBodyProto.Model bodyProto = ReplyBodyProto.Model.parseFrom(bytes);
|
||||
ReplyBody body = new ReplyBody();
|
||||
body.setKey(bodyProto.getKey());
|
||||
body.setTimestamp(bodyProto.getTimestamp());
|
||||
body.putAll(bodyProto.getDataMap());
|
||||
body.setCode(bodyProto.getCode());
|
||||
body.setMessage(bodyProto.getMessage());
|
||||
return body;
|
||||
}
|
||||
MessageProto.Model bodyProto = MessageProto.Model.parseFrom(bodyBuffer.array());
|
||||
Message message = new Message();
|
||||
message.setId(bodyProto.getId());
|
||||
message.setAction(bodyProto.getAction());
|
||||
message.setContent(bodyProto.getContent());
|
||||
message.setSender(bodyProto.getSender());
|
||||
message.setReceiver(bodyProto.getReceiver());
|
||||
message.setTitle(bodyProto.getTitle());
|
||||
message.setExtra(bodyProto.getExtra());
|
||||
message.setTimestamp(bodyProto.getTimestamp());
|
||||
message.setFormat(bodyProto.getFormat());
|
||||
return message;
|
||||
}
|
||||
|
||||
if (CIMConstant.ProtobufType.MESSAGE == type) {
|
||||
MessageProto.Model bodyProto = MessageProto.Model.parseFrom(bytes);
|
||||
Message message = new Message();
|
||||
message.setId(bodyProto.getId());
|
||||
message.setAction(bodyProto.getAction());
|
||||
message.setContent(bodyProto.getContent());
|
||||
message.setSender(bodyProto.getSender());
|
||||
message.setReceiver(bodyProto.getReceiver());
|
||||
message.setTitle(bodyProto.getTitle());
|
||||
message.setExtra(bodyProto.getExtra());
|
||||
message.setTimestamp(bodyProto.getTimestamp());
|
||||
message.setFormat(bodyProto.getFormat());
|
||||
return message;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析消息体长度
|
||||
*/
|
||||
private int getContentLength(byte lv, byte hv) {
|
||||
int l = (lv & 0xff);
|
||||
int h = (hv & 0xff);
|
||||
return (l | h << 8);
|
||||
}
|
||||
/**
|
||||
* 解析消息体长度
|
||||
*/
|
||||
private int getContentLength(byte lv, byte hv) {
|
||||
int l = (lv & 0xff);
|
||||
int h = (hv & 0xff);
|
||||
return (l | h << 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,38 +23,35 @@ package com.farsunset.cim.sdk.android.coder;
|
||||
|
||||
import com.farsunset.cim.sdk.android.constant.CIMConstant;
|
||||
import com.farsunset.cim.sdk.android.model.Protobufable;
|
||||
import com.farsunset.cim.sdk.android.model.SentBody;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* 客户端消息发送前进行编码
|
||||
*/
|
||||
public class ClientMessageEncoder {
|
||||
public class ClientMessageEncoder {
|
||||
|
||||
public ByteBuffer encode(Object object) {
|
||||
public ByteBuffer encode(Protobufable body) {
|
||||
|
||||
Protobufable data = (Protobufable) object;
|
||||
byte[] byteArray = data.getByteArray();
|
||||
byte[] data = body.getByteArray();
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocate(byteArray.length + CIMConstant.DATA_HEADER_LENGTH);
|
||||
ByteBuffer buffer = ByteBuffer.allocate(data.length + CIMConstant.DATA_HEADER_LENGTH);
|
||||
|
||||
buffer.put(createHeader(data.getType(), byteArray.length));
|
||||
buffer.put(byteArray);
|
||||
buffer.flip();
|
||||
buffer.put(createHeader(body.getType(), data.length));
|
||||
buffer.put(data);
|
||||
buffer.flip();
|
||||
|
||||
return buffer;
|
||||
return buffer;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息体最大为65535
|
||||
*/
|
||||
private byte[] createHeader(byte type, int length) {
|
||||
byte[] header = new byte[CIMConstant.DATA_HEADER_LENGTH];
|
||||
header[0] = type;
|
||||
header[1] = (byte) (length & 0xff);
|
||||
header[2] = (byte) ((length >> 8) & 0xff);
|
||||
return header;
|
||||
}
|
||||
/**
|
||||
* 消息体最大为65535
|
||||
*/
|
||||
private byte[] createHeader(byte type, int length) {
|
||||
byte[] header = new byte[CIMConstant.DATA_HEADER_LENGTH];
|
||||
header[0] = type;
|
||||
header[1] = (byte) (length & 0xff);
|
||||
header[2] = (byte) ((length >> 8) & 0xff);
|
||||
return header;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,99 +21,89 @@
|
||||
*/
|
||||
package com.farsunset.cim.sdk.android.constant;
|
||||
|
||||
/**
|
||||
* 常量
|
||||
*/
|
||||
public interface CIMConstant {
|
||||
|
||||
long RECONNECT_INTERVAL_TIME = 30 * 1000;
|
||||
long RECONNECT_INTERVAL_TIME = 30 * 1000;
|
||||
|
||||
/**
|
||||
消息头长度为3个字节,第一个字节为消息类型,第二,第三字节 转换int后为消息长度
|
||||
*/
|
||||
int DATA_HEADER_LENGTH = 3;
|
||||
/*
|
||||
* 消息头长度为3个字节,第一个字节为消息类型,第二,第三字节 转换int后为消息长度
|
||||
*/
|
||||
int DATA_HEADER_LENGTH = 3;
|
||||
|
||||
interface ReturnCode {
|
||||
interface ProtobufType {
|
||||
|
||||
String CODE_404 = "404";
|
||||
/*
|
||||
客户端->服务端 发送的心跳响应
|
||||
*/
|
||||
byte C_H_RS = 0;
|
||||
|
||||
String CODE_403 = "403";
|
||||
/*
|
||||
服务端->客户端 发送的心跳请求
|
||||
*/
|
||||
byte S_H_RQ = 1;
|
||||
|
||||
String CODE_405 = "405";
|
||||
byte MESSAGE = 2;
|
||||
|
||||
String CODE_200 = "200";
|
||||
byte SENT_BODY = 3;
|
||||
|
||||
String CODE_206 = "206";
|
||||
byte REPLY_BODY = 4;
|
||||
}
|
||||
|
||||
String CODE_500 = "500";
|
||||
interface RequestKey {
|
||||
|
||||
}
|
||||
String CLIENT_BIND = "client_bind";
|
||||
|
||||
interface ProtobufType {
|
||||
byte C_H_RS = 0;
|
||||
byte S_H_RQ = 1;
|
||||
byte MESSAGE = 2;
|
||||
byte SENT_BODY = 3;
|
||||
byte REPLY_BODY = 4;
|
||||
}
|
||||
}
|
||||
|
||||
interface RequestKey {
|
||||
interface MessageAction {
|
||||
|
||||
String CLIENT_BIND = "client_bind";
|
||||
/*
|
||||
被其他设备登录挤下线消息
|
||||
*/
|
||||
String ACTION_999 = "999";
|
||||
}
|
||||
|
||||
String CLIENT_LOGOUT = "client_logout";
|
||||
interface IntentAction {
|
||||
|
||||
}
|
||||
/*
|
||||
消息广播action
|
||||
*/
|
||||
String ACTION_MESSAGE_RECEIVED = "com.farsunset.cim.MESSAGE_RECEIVED";
|
||||
|
||||
interface MessageAction {
|
||||
/*
|
||||
发送sendBody成功广播
|
||||
*/
|
||||
String ACTION_SEND_FINISHED = "com.farsunset.cim.SEND_FINISHED";
|
||||
|
||||
/*
|
||||
被其他设备登录挤下线消息
|
||||
*/
|
||||
String ACTION_999 = "999";
|
||||
}
|
||||
/*
|
||||
链接意外关闭广播
|
||||
*/
|
||||
String ACTION_CONNECTION_CLOSED = "com.farsunset.cim.CONNECTION_CLOSED";
|
||||
|
||||
interface IntentAction {
|
||||
/*
|
||||
链接失败广播
|
||||
*/
|
||||
String ACTION_CONNECT_FAILED = "com.farsunset.cim.CONNECT_FAILED";
|
||||
|
||||
/*
|
||||
消息广播action
|
||||
*/
|
||||
String ACTION_MESSAGE_RECEIVED = "com.farsunset.cim.MESSAGE_RECEIVED";
|
||||
/*
|
||||
链接成功广播
|
||||
*/
|
||||
String ACTION_CONNECT_FINISHED = "com.farsunset.cim.CONNECT_FINISHED";
|
||||
|
||||
/*
|
||||
发送sendBody成功广播
|
||||
*/
|
||||
String ACTION_SEND_FINISHED = "com.farsunset.cim.SEND_FINISHED";
|
||||
/*
|
||||
发送sendBody成功后获得replayBody回应广播
|
||||
*/
|
||||
String ACTION_REPLY_RECEIVED = "com.farsunset.cim.REPLY_RECEIVED";
|
||||
|
||||
/*
|
||||
链接意外关闭广播
|
||||
*/
|
||||
String ACTION_CONNECTION_CLOSED = "com.farsunset.cim.CONNECTION_CLOSED";
|
||||
/*
|
||||
网络变化广播
|
||||
*/
|
||||
String ACTION_NETWORK_CHANGED = "com.farsunset.cim.NETWORK_CHANGED";
|
||||
|
||||
/*
|
||||
链接失败广播
|
||||
*/
|
||||
String ACTION_CONNECT_FAILED = "com.farsunset.cim.CONNECT_FAILED";
|
||||
|
||||
/*
|
||||
链接成功广播
|
||||
*/
|
||||
String ACTION_CONNECT_FINISHED = "com.farsunset.cim.CONNECT_FINISHED";
|
||||
|
||||
/*
|
||||
发送sendBody成功后获得replayBody回应广播
|
||||
*/
|
||||
String ACTION_REPLY_RECEIVED = "com.farsunset.cim.REPLY_RECEIVED";
|
||||
|
||||
/*
|
||||
网络变化广播
|
||||
*/
|
||||
String ACTION_NETWORK_CHANGED = "com.farsunset.cim.NETWORK_CHANGED";
|
||||
|
||||
/*
|
||||
重试连接
|
||||
*/
|
||||
String ACTION_CONNECTION_RECOVERY = "com.farsunset.cim.CONNECTION_RECOVERY";
|
||||
}
|
||||
/*
|
||||
重试连接
|
||||
*/
|
||||
String ACTION_CONNECTION_RECOVERY = "com.farsunset.cim.CONNECTION_RECOVERY";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************************
|
||||
* *
|
||||
* Website : http://www.farsunset.com *
|
||||
* *
|
||||
***************************************************************************************
|
||||
*/
|
||||
package com.farsunset.cim.sdk.android.logger;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
|
||||
/**
|
||||
* 日志打印,添加session 的id和ip address
|
||||
*/
|
||||
public class CIMLogger {
|
||||
private final static String TAG = "CIM";
|
||||
private boolean debug = true;
|
||||
|
||||
public static CIMLogger getLogger() {
|
||||
return LoggerHolder.logger;
|
||||
}
|
||||
|
||||
private CIMLogger() {
|
||||
|
||||
}
|
||||
|
||||
private static class LoggerHolder {
|
||||
private static final CIMLogger logger = new CIMLogger();
|
||||
}
|
||||
|
||||
public void debugMode(boolean mode) {
|
||||
debug = mode;
|
||||
}
|
||||
|
||||
public void messageReceived(SocketChannel session, Object message) {
|
||||
if (debug) {
|
||||
Log.i(TAG, String.format("[RECEIVED]" + getSessionInfo(session) + "\n%s", message));
|
||||
}
|
||||
}
|
||||
|
||||
public void messageSent(SocketChannel session, Object message) {
|
||||
if (debug) {
|
||||
Log.i(TAG, String.format("[ SENT ]" + getSessionInfo(session) + "\n%s", message));
|
||||
}
|
||||
}
|
||||
|
||||
public void sessionCreated(SocketChannel session) {
|
||||
if (debug) {
|
||||
Log.i(TAG, "[ OPENED ]" + getSessionInfo(session));
|
||||
}
|
||||
}
|
||||
|
||||
public void sessionIdle(SocketChannel session) {
|
||||
if (debug) {
|
||||
Log.d(TAG, "[ IDLE ]" + getSessionInfo(session));
|
||||
}
|
||||
}
|
||||
|
||||
public void sessionClosed(SocketChannel session) {
|
||||
if (debug) {
|
||||
Log.w(TAG, "[ CLOSED ] ID = " + session.hashCode());
|
||||
}
|
||||
}
|
||||
|
||||
public void connectFailure(long interval) {
|
||||
if (debug) {
|
||||
Log.d(TAG, "CONNECT FAILURE, TRY RECONNECT AFTER " + interval + "ms");
|
||||
}
|
||||
}
|
||||
|
||||
public void startConnect(String host, int port) {
|
||||
if (debug) {
|
||||
Log.i(TAG, "START CONNECT REMOTE HOST:" + host + " PORT:" + port);
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidHostPort(String host, int port) {
|
||||
if (debug) {
|
||||
Log.d(TAG, "INVALID SOCKET ADDRESS -> HOST:" + host + " PORT:" + port);
|
||||
}
|
||||
}
|
||||
|
||||
public void connectState(boolean isConnected, boolean isManualStop, boolean isDestroyed) {
|
||||
if (debug) {
|
||||
Log.d(TAG, "CONNECTED:" + isConnected + " STOPPED:" + isManualStop + " DESTROYED:" + isDestroyed);
|
||||
}
|
||||
}
|
||||
|
||||
private String getSessionInfo(SocketChannel session) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (session == null) {
|
||||
return "";
|
||||
}
|
||||
builder.append(" [");
|
||||
builder.append("id:").append(session.hashCode());
|
||||
|
||||
try {
|
||||
if (session.socket().getLocalAddress() != null) {
|
||||
builder.append(" L:").append(session.socket().getLocalAddress()).append(":").append(session.socket().getLocalPort());
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
if (session.socket().getRemoteSocketAddress() != null) {
|
||||
builder.append(" R:").append(session.socket().getRemoteSocketAddress().toString());
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -27,37 +27,36 @@ import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 服务端心跳请求
|
||||
*
|
||||
*/
|
||||
public class HeartbeatRequest implements Serializable, Protobufable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String TAG = "SERVER_HEARTBEAT_REQUEST";
|
||||
private static final String CMD_HEARTBEAT_REQUEST = "SR";
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String TAG = "SERVER_HEARTBEAT_REQUEST";
|
||||
private static final String CMD_HEARTBEAT_REQUEST = "SR";
|
||||
|
||||
private static HeartbeatRequest object = new HeartbeatRequest();
|
||||
private static final HeartbeatRequest object = new HeartbeatRequest();
|
||||
|
||||
private HeartbeatRequest() {
|
||||
private HeartbeatRequest() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static HeartbeatRequest getInstance() {
|
||||
return object;
|
||||
}
|
||||
public static HeartbeatRequest getInstance() {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getByteArray() {
|
||||
return CMD_HEARTBEAT_REQUEST.getBytes();
|
||||
}
|
||||
@Override
|
||||
public byte[] getByteArray() {
|
||||
return CMD_HEARTBEAT_REQUEST.getBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return TAG;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getType() {
|
||||
return CIMConstant.ProtobufType.S_H_RQ;
|
||||
}
|
||||
@Override
|
||||
public byte getType() {
|
||||
return CIMConstant.ProtobufType.S_H_RQ;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,33 +30,33 @@ import java.io.Serializable;
|
||||
*/
|
||||
public class HeartbeatResponse implements Serializable, Protobufable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String TAG = "CLIENT_HEARTBEAT_RESPONSE";
|
||||
private static final String CMD_HEARTBEAT_RESPONSE = "CR";
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String TAG = "CLIENT_HEARTBEAT_RESPONSE";
|
||||
private static final String CMD_HEARTBEAT_RESPONSE = "CR";
|
||||
|
||||
private static HeartbeatResponse object = new HeartbeatResponse();
|
||||
private static final HeartbeatResponse object = new HeartbeatResponse();
|
||||
|
||||
private HeartbeatResponse() {
|
||||
private HeartbeatResponse() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static HeartbeatResponse getInstance() {
|
||||
return object;
|
||||
}
|
||||
public static HeartbeatResponse getInstance() {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getByteArray() {
|
||||
return CMD_HEARTBEAT_RESPONSE.getBytes();
|
||||
}
|
||||
@Override
|
||||
public byte[] getByteArray() {
|
||||
return CMD_HEARTBEAT_RESPONSE.getBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return TAG;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getType() {
|
||||
return CIMConstant.ProtobufType.C_H_RS;
|
||||
}
|
||||
@Override
|
||||
public byte getType() {
|
||||
return CIMConstant.ProtobufType.C_H_RS;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,143 +28,143 @@ import java.io.Serializable;
|
||||
*/
|
||||
public class Message implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 消息类型,用户自定义消息类别
|
||||
*/
|
||||
private long id;
|
||||
/**
|
||||
* 消息类型,用户自定义消息类别
|
||||
*/
|
||||
private long id;
|
||||
|
||||
/**
|
||||
* 消息类型,用户自定义消息类别
|
||||
*/
|
||||
private String action;
|
||||
/**
|
||||
* 消息标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 消息类容,于action 组合为任何类型消息,content 根据 format 可表示为 text,json ,xml数据格式
|
||||
*/
|
||||
private String content;
|
||||
/**
|
||||
* 消息类型,用户自定义消息类别
|
||||
*/
|
||||
private String action;
|
||||
/**
|
||||
* 消息标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 消息类容,于action 组合为任何类型消息,content 根据 format 可表示为 text,json ,xml数据格式
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 消息发送者账号
|
||||
*/
|
||||
private String sender;
|
||||
/**
|
||||
* 消息发送者接收者
|
||||
*/
|
||||
private String receiver;
|
||||
/**
|
||||
* 消息发送者账号
|
||||
*/
|
||||
private String sender;
|
||||
/**
|
||||
* 消息发送者接收者
|
||||
*/
|
||||
private String receiver;
|
||||
|
||||
/**
|
||||
* content 内容格式
|
||||
*/
|
||||
private String format;
|
||||
/**
|
||||
* content 内容格式
|
||||
*/
|
||||
private String format;
|
||||
|
||||
/**
|
||||
* 附加内容 内容
|
||||
*/
|
||||
private String extra;
|
||||
/**
|
||||
* 附加内容 内容
|
||||
*/
|
||||
private String extra;
|
||||
|
||||
private long timestamp;
|
||||
private long timestamp;
|
||||
|
||||
public Message() {
|
||||
timestamp = System.currentTimeMillis();
|
||||
}
|
||||
public Message() {
|
||||
timestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public void setAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
public void setAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getSender() {
|
||||
return sender;
|
||||
}
|
||||
public String getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public void setSender(String sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
public void setSender(String sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
public String getReceiver() {
|
||||
return receiver;
|
||||
}
|
||||
public String getReceiver() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
public void setReceiver(String receiver) {
|
||||
this.receiver = receiver;
|
||||
}
|
||||
public void setReceiver(String receiver) {
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
public String getFormat() {
|
||||
return format;
|
||||
}
|
||||
public String getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
public void setFormat(String format) {
|
||||
this.format = format;
|
||||
}
|
||||
public void setFormat(String format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public String getExtra() {
|
||||
return extra;
|
||||
}
|
||||
public String getExtra() {
|
||||
return extra;
|
||||
}
|
||||
|
||||
public void setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
}
|
||||
public void setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("#Message#").append("\n");
|
||||
buffer.append("id:").append(id).append("\n");
|
||||
buffer.append("action:").append(action).append("\n");
|
||||
buffer.append("title:").append(title).append("\n");
|
||||
buffer.append("content:").append(content).append("\n");
|
||||
buffer.append("extra:").append(extra).append("\n");
|
||||
buffer.append("sender:").append(sender).append("\n");
|
||||
buffer.append("receiver:").append(receiver).append("\n");
|
||||
buffer.append("format:").append(format).append("\n");
|
||||
buffer.append("timestamp:").append(timestamp);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("#Message#").append("\n");
|
||||
buffer.append("id:").append(id).append("\n");
|
||||
buffer.append("action:").append(action).append("\n");
|
||||
buffer.append("title:").append(title).append("\n");
|
||||
buffer.append("content:").append(content).append("\n");
|
||||
buffer.append("extra:").append(extra).append("\n");
|
||||
buffer.append("sender:").append(sender).append("\n");
|
||||
buffer.append("receiver:").append(receiver).append("\n");
|
||||
buffer.append("format:").append(format).append("\n");
|
||||
buffer.append("timestamp:").append(timestamp);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public boolean isNotEmpty(String txt) {
|
||||
return txt != null && txt.trim().length() != 0;
|
||||
}
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public boolean isNotEmpty(String txt) {
|
||||
return txt != null && txt.trim().length() != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ package com.farsunset.cim.sdk.android.model;
|
||||
*/
|
||||
public interface Protobufable {
|
||||
|
||||
byte[] getByteArray();
|
||||
byte[] getByteArray();
|
||||
|
||||
byte getType();
|
||||
byte getType();
|
||||
}
|
||||
|
@ -28,101 +28,100 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* 请求应答对象
|
||||
*
|
||||
*/
|
||||
public class ReplyBody implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 请求key
|
||||
*/
|
||||
private String key;
|
||||
/**
|
||||
* 请求key
|
||||
*/
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 返回码
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 返回码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 返回说明
|
||||
*/
|
||||
private String message;
|
||||
/**
|
||||
* 返回说明
|
||||
*/
|
||||
private String message;
|
||||
|
||||
private long timestamp;
|
||||
private long timestamp;
|
||||
|
||||
/**
|
||||
* 返回数据集合
|
||||
*/
|
||||
private Hashtable<String, String> data = new Hashtable<String, String>();
|
||||
/**
|
||||
* 返回数据集合
|
||||
*/
|
||||
private final Hashtable<String, String> data = new Hashtable<String, String>();
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public void put(String k, String v) {
|
||||
data.put(k, v);
|
||||
}
|
||||
public void put(String k, String v) {
|
||||
data.put(k, v);
|
||||
}
|
||||
|
||||
public String get(String k) {
|
||||
return data.get(k);
|
||||
}
|
||||
public String get(String k) {
|
||||
return data.get(k);
|
||||
}
|
||||
|
||||
public void remove(String k) {
|
||||
data.remove(k);
|
||||
}
|
||||
public void remove(String k) {
|
||||
data.remove(k);
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void putAll(Map<String, String> map) {
|
||||
data.putAll(map);
|
||||
}
|
||||
public void putAll(Map<String, String> map) {
|
||||
data.putAll(map);
|
||||
}
|
||||
|
||||
public Set<String> getKeySet() {
|
||||
return data.keySet();
|
||||
}
|
||||
public Set<String> getKeySet() {
|
||||
return data.keySet();
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("#ReplyBody#").append("\n");
|
||||
buffer.append("key:").append(this.getKey()).append("\n");
|
||||
buffer.append("timestamp:").append(timestamp).append("\n");
|
||||
buffer.append("code:").append(code).append("\n");
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("#ReplyBody#").append("\n");
|
||||
buffer.append("key:").append(this.getKey()).append("\n");
|
||||
buffer.append("timestamp:").append(timestamp).append("\n");
|
||||
buffer.append("code:").append(code).append("\n");
|
||||
|
||||
buffer.append("data{").append("\n");
|
||||
for (String key : getKeySet()) {
|
||||
buffer.append(key).append(":").append(this.get(key)).append("\n");
|
||||
}
|
||||
buffer.append("}");
|
||||
buffer.append("data{").append("\n");
|
||||
for (String key : getKeySet()) {
|
||||
buffer.append(key).append(":").append(this.get(key)).append("\n");
|
||||
}
|
||||
buffer.append("}");
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,85 +30,84 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* java |android 客户端请求结构
|
||||
*
|
||||
*/
|
||||
public class SentBody implements Serializable, Protobufable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String key;
|
||||
private String key;
|
||||
|
||||
private Hashtable<String, String> data = new Hashtable<String, String>();;
|
||||
private final Hashtable<String, String> data = new Hashtable<String, String>();
|
||||
|
||||
private long timestamp;
|
||||
private long timestamp;
|
||||
|
||||
public SentBody() {
|
||||
timestamp = System.currentTimeMillis();
|
||||
}
|
||||
public SentBody() {
|
||||
timestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String get(String k) {
|
||||
return data.get(k);
|
||||
}
|
||||
public String get(String k) {
|
||||
return data.get(k);
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public void put(String k, String v) {
|
||||
if (k == null || v == null) {
|
||||
return;
|
||||
}
|
||||
data.put(k, v);
|
||||
}
|
||||
public void put(String k, String v) {
|
||||
if (k == null || v == null) {
|
||||
return;
|
||||
}
|
||||
data.put(k, v);
|
||||
}
|
||||
|
||||
public Set<String> getKeySet() {
|
||||
return data.keySet();
|
||||
}
|
||||
public Set<String> getKeySet() {
|
||||
return data.keySet();
|
||||
}
|
||||
|
||||
public void remove(String k) {
|
||||
data.remove(k);
|
||||
}
|
||||
public void remove(String k) {
|
||||
data.remove(k);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("#SentBody#").append("\n");
|
||||
buffer.append("key:").append(key).append("\n");
|
||||
buffer.append("timestamp:").append(timestamp).append("\n");
|
||||
buffer.append("data{").append("\n");
|
||||
for (String key : getKeySet()) {
|
||||
buffer.append(key).append(":").append(this.get(key)).append("\n");
|
||||
}
|
||||
buffer.append("}");
|
||||
return buffer.toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("#SentBody#").append("\n");
|
||||
buffer.append("key:").append(key).append("\n");
|
||||
buffer.append("timestamp:").append(timestamp).append("\n");
|
||||
buffer.append("data{").append("\n");
|
||||
for (String key : getKeySet()) {
|
||||
buffer.append(key).append(":").append(this.get(key)).append("\n");
|
||||
}
|
||||
buffer.append("}");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getByteArray() {
|
||||
SentBodyProto.Model.Builder builder = SentBodyProto.Model.newBuilder();
|
||||
builder.setKey(key);
|
||||
builder.setTimestamp(timestamp);
|
||||
if (!data.isEmpty()) {
|
||||
builder.putAllData(data);
|
||||
}
|
||||
return builder.build().toByteArray();
|
||||
}
|
||||
@Override
|
||||
public byte[] getByteArray() {
|
||||
SentBodyProto.Model.Builder builder = SentBodyProto.Model.newBuilder();
|
||||
builder.setKey(key);
|
||||
builder.setTimestamp(timestamp);
|
||||
if (!data.isEmpty()) {
|
||||
builder.putAllData(data);
|
||||
}
|
||||
return builder.build().toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getType() {
|
||||
return CIMConstant.ProtobufType.SENT_BODY;
|
||||
}
|
||||
@Override
|
||||
public byte getType() {
|
||||
return CIMConstant.ProtobufType.SENT_BODY;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
syntax = "proto3";
|
||||
package com.farsunset.cim.sdk.android.model.proto;
|
||||
option java_outer_classname="MessageProto";
|
||||
option java_outer_classname = "MessageProto";
|
||||
message Model {
|
||||
int64 id = 1;
|
||||
string action = 2;
|
||||
string content = 3;
|
||||
string sender = 4;
|
||||
string receiver = 5;
|
||||
string extra = 6;
|
||||
string title = 7;
|
||||
string format = 8;
|
||||
int64 timestamp = 9;
|
||||
int64 id = 1;
|
||||
string action = 2;
|
||||
string content = 3;
|
||||
string sender = 4;
|
||||
string receiver = 5;
|
||||
string extra = 6;
|
||||
string title = 7;
|
||||
string format = 8;
|
||||
int64 timestamp = 9;
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
syntax = "proto3";
|
||||
package com.farsunset.cim.sdk.android.model.proto;
|
||||
option java_outer_classname="ReplyBodyProto";
|
||||
option java_outer_classname = "ReplyBodyProto";
|
||||
|
||||
message Model {
|
||||
string key = 1;
|
||||
string code = 2;
|
||||
string message = 3;
|
||||
int64 timestamp =4;
|
||||
map<string,string> data =5;
|
||||
|
||||
string key = 1;
|
||||
string code = 2;
|
||||
string message = 3;
|
||||
int64 timestamp = 4;
|
||||
map<string, string> data = 5;
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
syntax = "proto3";
|
||||
package com.farsunset.cim.sdk.android.model.proto;
|
||||
option java_outer_classname="SentBodyProto";
|
||||
option java_outer_classname = "SentBodyProto";
|
||||
|
||||
message Model {
|
||||
string key = 1;
|
||||
int64 timestamp =2;
|
||||
map<string,string> data =3;
|
||||
|
||||
string key = 1;
|
||||
int64 timestamp = 2;
|
||||
map<string, string> data = 3;
|
||||
|
||||
}
|
||||
|
15
cim-client-sdk/cim-java-sdk/cim-java-sdk.iml
Normal file → Executable file
15
cim-client-sdk/cim-java-sdk/cim-java-sdk.iml
Normal file → Executable file
@ -1,2 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4" />
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: com.google.protobuf:protobuf-java:3.11.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
|
||||
</component>
|
||||
</module>
|
0
cim-client-sdk/cim-java-sdk/jar.bat
Normal file → Executable file
0
cim-client-sdk/cim-java-sdk/jar.bat
Normal file → Executable file
0
cim-client-sdk/cim-java-sdk/jar.sh
Normal file → Executable file
0
cim-client-sdk/cim-java-sdk/jar.sh
Normal file → Executable file
0
cim-client-sdk/cim-java-sdk/pom.xml
Normal file → Executable file
0
cim-client-sdk/cim-java-sdk/pom.xml
Normal file → Executable file
@ -25,7 +25,7 @@ import java.util.HashMap;
|
||||
|
||||
class CIMCacheManager {
|
||||
|
||||
private static HashMap<String, String> CIM_CONFIG_INFO = new HashMap<String, String>();
|
||||
private static final HashMap<String, String> CIM_CONFIG_INFO = new HashMap<String, String>();
|
||||
|
||||
public static final String KEY_MANUAL_STOP = "KEY_MANUAL_STOP";
|
||||
|
||||
|
@ -30,7 +30,6 @@ import java.nio.channels.SocketChannel;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import com.farsunset.cim.sdk.client.coder.CIMLogger;
|
||||
import com.farsunset.cim.sdk.client.coder.ClientMessageDecoder;
|
||||
@ -64,18 +63,17 @@ class CIMConnectorManager {
|
||||
|
||||
private ByteBuffer readBuffer = ByteBuffer.allocate(READ_BUFFER_SIZE);
|
||||
|
||||
private ExecutorService workerExecutor = Executors.newFixedThreadPool(1, r -> new Thread(r,"worker-"));
|
||||
private ExecutorService bossExecutor = Executors.newFixedThreadPool(1, r -> new Thread(r,"boss-"));
|
||||
private ExecutorService eventExecutor = Executors.newFixedThreadPool(1, r -> new Thread(r,"event-"));
|
||||
private final ExecutorService workerExecutor = Executors.newFixedThreadPool(1, r -> new Thread(r,"worker-"));
|
||||
private final ExecutorService bossExecutor = Executors.newFixedThreadPool(1, r -> new Thread(r,"boss-"));
|
||||
private final ExecutorService eventExecutor = Executors.newFixedThreadPool(1, r -> new Thread(r,"event-"));
|
||||
|
||||
private Semaphore semaphore = new Semaphore(1, true);
|
||||
|
||||
|
||||
private ClientMessageEncoder messageEncoder = new ClientMessageEncoder();
|
||||
private ClientMessageDecoder messageDecoder = new ClientMessageDecoder();
|
||||
|
||||
|
||||
|
||||
private final ClientMessageEncoder messageEncoder = new ClientMessageEncoder();
|
||||
private final ClientMessageDecoder messageDecoder = new ClientMessageDecoder();
|
||||
|
||||
private final ByteBuffer headerBuffer = ByteBuffer.allocate(CIMConstant.DATA_HEADER_LENGTH);
|
||||
|
||||
|
||||
public synchronized static CIMConnectorManager getManager() {
|
||||
|
||||
if (manager == null) {
|
||||
@ -105,8 +103,6 @@ class CIMConnectorManager {
|
||||
|
||||
try {
|
||||
|
||||
semaphore.acquire();
|
||||
|
||||
socketChannel = SocketChannel.open();
|
||||
socketChannel.configureBlocking(true);
|
||||
socketChannel.socket().setTcpNoDelay(true);
|
||||
@ -116,40 +112,30 @@ class CIMConnectorManager {
|
||||
|
||||
socketChannel.socket().connect(new InetSocketAddress(host, port),CONNECT_TIME_OUT);
|
||||
|
||||
semaphore.release();
|
||||
|
||||
handelConnectedEvent();
|
||||
handleConnectedEvent();
|
||||
|
||||
|
||||
int result = -1;
|
||||
|
||||
while((result = socketChannel.read(readBuffer)) > 0) {
|
||||
|
||||
if(readBuffer.position() == readBuffer.capacity()) {
|
||||
extendByteBuffer();
|
||||
}
|
||||
|
||||
handelSocketReadEvent(result);
|
||||
|
||||
/*
|
||||
*开始读取来自服务端的消息,先读取3个字节的消息头
|
||||
*/
|
||||
while (socketChannel.read(headerBuffer) > 0) {
|
||||
handleSocketReadEvent();
|
||||
}
|
||||
|
||||
handelSocketReadEvent(result);
|
||||
/*
|
||||
*read 返回 <= 0的情况,发生了意外需要断开重链
|
||||
*/
|
||||
closeSession();
|
||||
|
||||
}catch(ConnectException | SocketTimeoutException ignore){
|
||||
semaphore.release();
|
||||
handleConnectAbortedEvent();
|
||||
} catch(IOException ignore) {
|
||||
semaphore.release();
|
||||
handelDisconnectedEvent();
|
||||
}catch (InterruptedException ignore) {
|
||||
semaphore.release();
|
||||
handleDisconnectedEvent();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void handelDisconnectedEvent() {
|
||||
|
||||
private void handleDisconnectedEvent() {
|
||||
closeSession();
|
||||
}
|
||||
|
||||
@ -166,51 +152,27 @@ class CIMConnectorManager {
|
||||
|
||||
}
|
||||
|
||||
private void handelConnectedEvent() {
|
||||
private void handleConnectedEvent() {
|
||||
|
||||
sessionCreated();
|
||||
}
|
||||
|
||||
private void handelSocketReadEvent(int result) {
|
||||
|
||||
if(result == -1) {
|
||||
closeSession();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
readBuffer.position(0);
|
||||
|
||||
Object message = messageDecoder.doDecode(readBuffer);
|
||||
|
||||
if(message == null) {
|
||||
|
||||
private void handleSocketReadEvent() throws IOException {
|
||||
|
||||
Object message = messageDecoder.doDecode(headerBuffer,socketChannel);
|
||||
|
||||
LOGGER.messageReceived(socketChannel, message);
|
||||
|
||||
if (isHeartbeatRequest(message)) {
|
||||
send(HeartbeatResponse.getInstance());
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.messageReceived(socketChannel,message);
|
||||
|
||||
if(isHeartbeatRequest(message)) {
|
||||
|
||||
send(getHeartbeatResponse());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.messageReceived(message);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void extendByteBuffer() {
|
||||
|
||||
ByteBuffer newBuffer = ByteBuffer.allocate(readBuffer.capacity() + READ_BUFFER_SIZE / 2);
|
||||
readBuffer.position(0);
|
||||
newBuffer.put(readBuffer);
|
||||
|
||||
readBuffer.clear();
|
||||
readBuffer = newBuffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void send(final Protobufable body) {
|
||||
|
||||
if(!isConnected()) {
|
||||
@ -221,8 +183,6 @@ class CIMConnectorManager {
|
||||
int result = 0;
|
||||
try {
|
||||
|
||||
semaphore.acquire();
|
||||
|
||||
ByteBuffer buffer = messageEncoder.encode(body);
|
||||
while(buffer.hasRemaining()){
|
||||
result += socketChannel.write(buffer);
|
||||
@ -232,8 +192,6 @@ class CIMConnectorManager {
|
||||
result = -1;
|
||||
}finally {
|
||||
|
||||
semaphore.release();
|
||||
|
||||
if(result <= 0) {
|
||||
closeSession();
|
||||
}else {
|
||||
@ -302,10 +260,6 @@ class CIMConnectorManager {
|
||||
}
|
||||
}
|
||||
|
||||
public HeartbeatResponse getHeartbeatResponse() {
|
||||
return HeartbeatResponse.getInstance();
|
||||
}
|
||||
|
||||
public boolean isHeartbeatRequest(Object data) {
|
||||
return data instanceof HeartbeatRequest;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class CIMEventBroadcastReceiver {
|
||||
private static CIMEventBroadcastReceiver receiver;
|
||||
private CIMEventListener listener;
|
||||
|
||||
private ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, r -> {
|
||||
private final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, r -> {
|
||||
Thread thread = new Thread(r);
|
||||
thread.setName("cim-reconnect-");
|
||||
return thread;
|
||||
|
@ -36,8 +36,8 @@ import com.farsunset.cim.sdk.client.model.ReplyBody;
|
||||
*/
|
||||
public class CIMListenerManager {
|
||||
|
||||
private static ArrayList<CIMEventListener> cimListeners = new ArrayList<CIMEventListener>();
|
||||
private static CIMMessageReceiveComparator comparator = new CIMMessageReceiveComparator();
|
||||
private static final ArrayList<CIMEventListener> cimListeners = new ArrayList<CIMEventListener>();
|
||||
private static final CIMMessageReceiveComparator comparator = new CIMMessageReceiveComparator();
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CIMListenerManager.class);
|
||||
|
||||
public static void registerMessageListener(CIMEventListener listener) {
|
||||
@ -56,9 +56,9 @@ public class CIMListenerManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyOnConnectionSuccessed(boolean antoBind) {
|
||||
public static void notifyOnConnectFinished(boolean autoBind) {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onConnectFinished(antoBind);
|
||||
listener.onConnectFinished(autoBind);
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,13 +80,13 @@ public class CIMListenerManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyOnConnectionFailed() {
|
||||
public static void notifyOnConnectFailed() {
|
||||
for (CIMEventListener listener : cimListeners) {
|
||||
listener.onConnectFailed();
|
||||
}
|
||||
}
|
||||
|
||||
public static void destory() {
|
||||
public static void destroy() {
|
||||
cimListeners.clear();
|
||||
}
|
||||
|
||||
|
@ -87,10 +87,10 @@ public class CIMPushManager {
|
||||
|
||||
protected static void connect() {
|
||||
|
||||
boolean isManualStop = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
|
||||
boolean isManualDestroy = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
boolean isManualStopped = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
|
||||
boolean isManualDestroyed = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
|
||||
if (isManualStop || isManualDestroy) {
|
||||
if (isManualStopped || isManualDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -124,8 +124,8 @@ public class CIMPushManager {
|
||||
*/
|
||||
public static void bindAccount(String account) {
|
||||
|
||||
boolean isManualDestroy = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
if (isManualDestroy || account == null || account.trim().length() == 0) {
|
||||
boolean isManualDestroyed = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
if (isManualDestroyed || account == null || account.trim().length() == 0) {
|
||||
return;
|
||||
}
|
||||
sendBindRequest(account);
|
||||
@ -136,9 +136,9 @@ public class CIMPushManager {
|
||||
|
||||
String account = getAccount();
|
||||
|
||||
boolean isManualDestory = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
boolean isManualStoped = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
|
||||
if (isManualStoped || account == null || account.trim().length() == 0 || isManualDestory) {
|
||||
boolean isManualDestroyed = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
boolean isManualStopped = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
|
||||
if (isManualStopped || account == null || account.trim().length() == 0 || isManualDestroyed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -154,10 +154,10 @@ public class CIMPushManager {
|
||||
*/
|
||||
public static void sendRequest(SentBody body) {
|
||||
|
||||
boolean isManualStop = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
|
||||
boolean isManualDestroy = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
boolean isManualStopped = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
|
||||
boolean isManualDestroyed = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
|
||||
if (isManualStop || isManualDestroy) {
|
||||
if (isManualStopped || isManualDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -174,8 +174,8 @@ public class CIMPushManager {
|
||||
*/
|
||||
public static void stop() {
|
||||
|
||||
boolean isManualDestroy = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
if (isManualDestroy) {
|
||||
boolean isManualDestroyed = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
if (isManualDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -199,12 +199,12 @@ public class CIMPushManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新恢复接收推送,重新连接服务端,并登录当前账号如果aotuBind == true
|
||||
* 重新恢复接收推送,重新连接服务端,并登录当前账号如果autoBind == true
|
||||
*/
|
||||
public static void resume() {
|
||||
|
||||
boolean isManualDestroy = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
if (isManualDestroy) {
|
||||
boolean isManualDestroyed = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
if (isManualDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -216,13 +216,13 @@ public class CIMPushManager {
|
||||
}
|
||||
|
||||
public static int getState() {
|
||||
boolean isManualDestroy = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
if (isManualDestroy) {
|
||||
boolean isManualDestroyed = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_CIM_DESTROYED);
|
||||
if (isManualDestroyed) {
|
||||
return STATE_DESTROYED;
|
||||
}
|
||||
|
||||
boolean isManualStop = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
|
||||
if (isManualStop) {
|
||||
boolean isManualStopped = CIMCacheManager.getInstance().getBoolean(CIMCacheManager.KEY_MANUAL_STOP);
|
||||
if (isManualStopped) {
|
||||
return STATE_STOPPED;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ import com.farsunset.cim.sdk.client.model.SentBody;
|
||||
*/
|
||||
public class CIMPushService {
|
||||
|
||||
private CIMConnectorManager manager;
|
||||
private final CIMConnectorManager manager;
|
||||
|
||||
private static CIMPushService service;
|
||||
|
||||
|
@ -42,7 +42,7 @@ public class CIMLogger {
|
||||
}
|
||||
|
||||
private static class LoggerHolder{
|
||||
private static CIMLogger logger = new CIMLogger();
|
||||
private static final CIMLogger logger = new CIMLogger();
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,7 +22,9 @@
|
||||
package com.farsunset.cim.sdk.client.coder;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
import com.farsunset.cim.sdk.client.constant.CIMConstant;
|
||||
import com.farsunset.cim.sdk.client.model.HeartbeatRequest;
|
||||
@ -30,60 +32,56 @@ import com.farsunset.cim.sdk.client.model.Message;
|
||||
import com.farsunset.cim.sdk.client.model.ReplyBody;
|
||||
import com.farsunset.cim.sdk.model.proto.MessageProto;
|
||||
import com.farsunset.cim.sdk.model.proto.ReplyBodyProto;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
/**
|
||||
* 客户端消息解码
|
||||
*/
|
||||
public class ClientMessageDecoder {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param headerBuffer 读取到的消息头
|
||||
* @param socketChannel
|
||||
* @return
|
||||
*/
|
||||
|
||||
public Object doDecode(ByteBuffer headerBuffer , SocketChannel socketChannel) throws IOException {
|
||||
|
||||
headerBuffer.position(0);
|
||||
|
||||
byte type = headerBuffer.get();
|
||||
byte lv = headerBuffer.get();
|
||||
byte hv = headerBuffer.get();
|
||||
|
||||
headerBuffer.clear();
|
||||
|
||||
public Object doDecode(ByteBuffer iobuffer) {
|
||||
|
||||
/*
|
||||
* 消息头3位
|
||||
* 先通过消息头拿到消息的长度,然后进行定长读取
|
||||
* 解决消息的断包和粘包情况
|
||||
*/
|
||||
if (iobuffer.remaining() < CIMConstant.DATA_HEADER_LENGTH) {
|
||||
return null;
|
||||
}
|
||||
|
||||
iobuffer.mark();
|
||||
int dataLength = getContentLength(lv, hv);
|
||||
|
||||
byte type = iobuffer.get();
|
||||
ByteBuffer bodyBuffer = ByteBuffer.allocate(dataLength);
|
||||
|
||||
byte lv = iobuffer.get();
|
||||
byte hv = iobuffer.get();
|
||||
/*
|
||||
* 如果读取的消息长度不够,则进行等待后续消息到来
|
||||
* 当读取的消息长度(bodyBuffer.position() == dataLength)时意味着一个完整的消息已经接收完成
|
||||
*/
|
||||
do {
|
||||
socketChannel.read(bodyBuffer);
|
||||
} while (bodyBuffer.position() != dataLength);
|
||||
|
||||
int length = getContentLength(lv, hv);
|
||||
|
||||
// 如果消息体没有接收完整,则重置读取,等待下一次重新读取
|
||||
if (length > iobuffer.remaining()) {
|
||||
iobuffer.reset();
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] dataBytes = new byte[length];
|
||||
iobuffer.get(dataBytes, 0, length);
|
||||
|
||||
iobuffer.position(0);
|
||||
|
||||
try {
|
||||
return mappingMessageObject(dataBytes, type);
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Object mappingMessageObject(byte[] bytes, byte type) throws InvalidProtocolBufferException {
|
||||
|
||||
/*
|
||||
消息读取完成后,通过type来解析成对应的消息体
|
||||
*/
|
||||
if (CIMConstant.ProtobufType.S_H_RQ == type) {
|
||||
return HeartbeatRequest.getInstance();
|
||||
}
|
||||
|
||||
if (CIMConstant.ProtobufType.REPLY_BODY == type) {
|
||||
ReplyBodyProto.Model bodyProto = ReplyBodyProto.Model.parseFrom(bytes);
|
||||
ReplyBodyProto.Model bodyProto = ReplyBodyProto.Model.parseFrom(bodyBuffer.array());
|
||||
ReplyBody body = new ReplyBody();
|
||||
body.setKey(bodyProto.getKey());
|
||||
body.setTimestamp(bodyProto.getTimestamp());
|
||||
@ -93,29 +91,22 @@ public class ClientMessageDecoder {
|
||||
return body;
|
||||
}
|
||||
|
||||
if (CIMConstant.ProtobufType.MESSAGE == type) {
|
||||
MessageProto.Model bodyProto = MessageProto.Model.parseFrom(bytes);
|
||||
Message message = new Message();
|
||||
message.setId(bodyProto.getId());
|
||||
message.setAction(bodyProto.getAction());
|
||||
message.setContent(bodyProto.getContent());
|
||||
message.setSender(bodyProto.getSender());
|
||||
message.setReceiver(bodyProto.getReceiver());
|
||||
message.setTitle(bodyProto.getTitle());
|
||||
message.setExtra(bodyProto.getExtra());
|
||||
message.setTimestamp(bodyProto.getTimestamp());
|
||||
message.setFormat(bodyProto.getFormat());
|
||||
return message;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
MessageProto.Model bodyProto = MessageProto.Model.parseFrom(bodyBuffer.array());
|
||||
Message message = new Message();
|
||||
message.setId(bodyProto.getId());
|
||||
message.setAction(bodyProto.getAction());
|
||||
message.setContent(bodyProto.getContent());
|
||||
message.setSender(bodyProto.getSender());
|
||||
message.setReceiver(bodyProto.getReceiver());
|
||||
message.setTitle(bodyProto.getTitle());
|
||||
message.setExtra(bodyProto.getExtra());
|
||||
message.setTimestamp(bodyProto.getTimestamp());
|
||||
message.setFormat(bodyProto.getFormat());
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析消息体长度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private int getContentLength(byte lv, byte hv) {
|
||||
int l = (lv & 0xff);
|
||||
@ -123,4 +114,5 @@ public class ClientMessageDecoder {
|
||||
return (l | h << 8);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -32,15 +32,14 @@ import com.farsunset.cim.sdk.client.model.Protobufable;
|
||||
*/
|
||||
public class ClientMessageEncoder {
|
||||
|
||||
public ByteBuffer encode(Object object) {
|
||||
public ByteBuffer encode(Protobufable body) {
|
||||
|
||||
Protobufable data = (Protobufable) object;
|
||||
byte[] byteArray = data.getByteArray();
|
||||
byte[] data = body.getByteArray();
|
||||
|
||||
ByteBuffer ioBuffer = ByteBuffer.allocate(byteArray.length + CIMConstant.DATA_HEADER_LENGTH);
|
||||
ByteBuffer ioBuffer = ByteBuffer.allocate(data.length + CIMConstant.DATA_HEADER_LENGTH);
|
||||
|
||||
ioBuffer.put(createHeader(data.getType(), byteArray.length));
|
||||
ioBuffer.put(byteArray);
|
||||
ioBuffer.put(createHeader(body.getType(), data.length));
|
||||
ioBuffer.put(data);
|
||||
ioBuffer.flip();
|
||||
|
||||
return ioBuffer;
|
||||
|
@ -27,26 +27,11 @@ package com.farsunset.cim.sdk.client.constant;
|
||||
public interface CIMConstant {
|
||||
|
||||
long RECONNECT_INTERVAL_TIME = 30 * 1000;
|
||||
/**
|
||||
/*
|
||||
* 消息头长度为3个字节,第一个字节为消息类型,第二,第三字节 转换int后为消息长度
|
||||
*/
|
||||
int DATA_HEADER_LENGTH = 3;
|
||||
|
||||
interface ReturnCode {
|
||||
|
||||
String CODE_404 = "404";
|
||||
|
||||
String CODE_403 = "403";
|
||||
|
||||
String CODE_405 = "405";
|
||||
|
||||
String CODE_200 = "200";
|
||||
|
||||
String CODE_206 = "206";
|
||||
|
||||
String CODE_500 = "500";
|
||||
|
||||
}
|
||||
|
||||
interface ConfigKey {
|
||||
|
||||
|
@ -35,7 +35,7 @@ public class HeartbeatRequest implements Serializable, Protobufable {
|
||||
private static final String TAG = "SERVER_HEARTBEAT_REQUEST";
|
||||
private static final String CMD_HEARTBEAT_RESPONSE = "SR";
|
||||
|
||||
private static HeartbeatRequest object = new HeartbeatRequest();
|
||||
private static final HeartbeatRequest object = new HeartbeatRequest();
|
||||
|
||||
private HeartbeatRequest() {
|
||||
|
||||
|
@ -34,7 +34,7 @@ public class HeartbeatResponse implements Serializable, Protobufable {
|
||||
private static final String TAG = "CLIENT_HEARTBEAT_RESPONSE";
|
||||
private static final String CMD_HEARTBEAT_RESPONSE = "CR";
|
||||
|
||||
private static HeartbeatResponse object = new HeartbeatResponse();
|
||||
private static final HeartbeatResponse object = new HeartbeatResponse();
|
||||
|
||||
private HeartbeatResponse() {
|
||||
|
||||
|
@ -34,7 +34,7 @@ public class Intent implements Serializable {
|
||||
|
||||
private String action;
|
||||
|
||||
private HashMap<String, Object> data = new HashMap<String, Object>();
|
||||
private final HashMap<String, Object> data = new HashMap<String, Object>();
|
||||
|
||||
public Intent() {
|
||||
}
|
||||
|
Binary file not shown.
11
cim-use-examples/cim-client-android/.idea/gradle.xml
generated
11
cim-use-examples/cim-client-android/.idea/gradle.xml
generated
@ -1,13 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<compositeConfiguration>
|
||||
<compositeBuild compositeDefinitionSource="SCRIPT" />
|
||||
</compositeConfiguration>
|
||||
<option name="testRunner" value="PLATFORM" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
|
@ -4,6 +4,8 @@
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/cim-client-android.iml" filepath="$PROJECT_DIR$/cim-client-android.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/app/cim-client-android-app.iml" filepath="$PROJECT_DIR$/app/cim-client-android-app.iml" group="cim-client-android/app" />
|
||||
<module fileurl="file://$PROJECT_DIR$/cim-use-examples-cim-client-android.iml" filepath="$PROJECT_DIR$/cim-use-examples-cim-client-android.iml" group="cim-client-android" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
Binary file not shown.
@ -65,11 +65,6 @@ public class SystemMsgListViewAdapter extends BaseAdapter {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyDataSetChanged() {
|
||||
//Collections.sort(list, new MessageTimeDescComparator());
|
||||
}
|
||||
|
||||
@SuppressLint("ViewHolder")
|
||||
@Override
|
||||
public View getView(int position, View chatItemView, ViewGroup parent) {
|
||||
|
@ -24,7 +24,7 @@ package com.farsunset.ichat.example.app;
|
||||
public interface Constant {
|
||||
|
||||
//服务端IP地址
|
||||
String CIM_SERVER_HOST = "192.168.1.88";
|
||||
String CIM_SERVER_HOST = "192.168.2.103";
|
||||
|
||||
//注意,这里的端口不是tomcat的端口,没改动就使用默认的23456
|
||||
int CIM_SERVER_PORT = 23456;
|
||||
|
@ -88,7 +88,7 @@ public class LoginActivity extends CIMMonitorActivity implements OnClickListener
|
||||
/*
|
||||
* 收到code为200的回应 账号绑定成功
|
||||
*/
|
||||
if (reply.getKey().equals(CIMConstant.RequestKey.CLIENT_BIND) && reply.getCode().equals(CIMConstant.ReturnCode.CODE_200)) {
|
||||
if (reply.getKey().equals(CIMConstant.RequestKey.CLIENT_BIND) && reply.getCode().equals("200")) {
|
||||
Intent intent = new Intent(this, SystemMessageActivity.class);
|
||||
intent.putExtra("account", accountEdit.getText().toString().trim());
|
||||
startActivity(intent);
|
||||
|
@ -87,9 +87,14 @@ public class SystemMessageActivity extends CIMMonitorActivity implements OnClick
|
||||
startActivity(intent);
|
||||
this.finish();
|
||||
} else {
|
||||
list.add(message);
|
||||
list.add(0,message);
|
||||
adapter.notifyDataSetChanged();
|
||||
chatListView.setSelection(chatListView.getTop());
|
||||
chatListView.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
chatListView.setSelection(0);
|
||||
}
|
||||
},500);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ buildscript {
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||
classpath 'com.android.tools.build:gradle:3.6.1'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
@ -1,7 +1,6 @@
|
||||
#Mon May 13 14:19:31 CST 2019
|
||||
#Fri Mar 06 13:42:48 CST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
|
||||
|
24
cim-use-examples/cim-client-java/cim-java-client.iml
Normal file
24
cim-use-examples/cim-client-java/cim-java-client.iml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: com.google.protobuf:protobuf-java:3.11.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
|
||||
<orderEntry type="module-library">
|
||||
<library name="Maven: com.farsunset:cim-java-sdk:3.8.0">
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/libs/cim-java-sdk-3.8.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
</component>
|
||||
</module>
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user