init mogo httpdns sdk

This commit is contained in:
tongchenfei
2021-01-19 19:38:46 +08:00
parent d5075235a7
commit 37a607d5df
26 changed files with 880 additions and 1 deletions

6
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.8" />
</component>
</project>

2
.idea/gradle.xml generated
View File

@@ -13,10 +13,12 @@
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/foudations" />
<option value="$PROJECT_DIR$/foudations/mogo-httpdns" />
<option value="$PROJECT_DIR$/foudations/mogo-passport" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="useQualifiedModuleNames" value="true" />
</GradleProjectSettings>
</option>
</component>

View File

@@ -0,0 +1,36 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="date" />
</inspection_tool>
</profile>
</component>

2
.idea/misc.xml generated
View File

@@ -4,7 +4,7 @@
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@@ -0,0 +1,135 @@
Index: build.gradle
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>// Top-level build file where you can add configuration options common to all sub-projects/modules.\napply from: \"config.gradle\"\n\nbuildscript {\n repositories {\n maven {\n url 'http://maven.aliyun.com/nexus/content/groups/public/'\n }\n maven {\n url 'http://nexus.zhidaoauto.com/repository/maven-releases/'\n }\n maven {\n url 'http://nexus.zhidaoauto.com/repository/maven-public/'\n }\n google()\n jcenter()\n }\n dependencies {\n classpath \"com.android.tools.build:gradle:4.0.2\"\n\n // NOTE: Do not place your application dependencies here; they belong\n // in the individual module build.gradle files\n }\n}\n\nallprojects {\n repositories {\n maven {\n url 'http://maven.aliyun.com/nexus/content/groups/public/'\n }\n maven {\n url 'http://nexus.zhidaoauto.com/repository/maven-releases/'\n }\n maven {\n url 'http://nexus.zhidaoauto.com/repository/maven-public/'\n }\n google()\n jcenter()\n }\n}\n\ntask clean(type: Delete) {\n delete rootProject.buildDir\n}
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- build.gradle (revision 398e43b09b74ac1319d2bdb60e1bac0c018ce1ff)
+++ build.gradle (date 1611052524000)
@@ -2,6 +2,7 @@
apply from: "config.gradle"
buildscript {
+ ext.kotlin_version = "1.3.72"
repositories {
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
@@ -17,6 +18,7 @@
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.2"
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Index: .idea/inspectionProfiles/Project_Default.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- .idea/inspectionProfiles/Project_Default.xml (date 1611044633000)
+++ .idea/inspectionProfiles/Project_Default.xml (date 1611044633000)
@@ -0,0 +1,36 @@
+<component name="InspectionProjectProfileManager">
+ <profile version="1.0">
+ <option name="myName" value="Project Default" />
+ <inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="TOP_LEVEL_CLASS_OPTIONS">
+ <value>
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+ <option name="REQUIRED_TAGS" value="" />
+ </value>
+ </option>
+ <option name="INNER_CLASS_OPTIONS">
+ <value>
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+ <option name="REQUIRED_TAGS" value="" />
+ </value>
+ </option>
+ <option name="METHOD_OPTIONS">
+ <value>
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+ <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
+ </value>
+ </option>
+ <option name="FIELD_OPTIONS">
+ <value>
+ <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+ <option name="REQUIRED_TAGS" value="" />
+ </value>
+ </option>
+ <option name="IGNORE_DEPRECATED" value="false" />
+ <option name="IGNORE_JAVADOC_PERIOD" value="true" />
+ <option name="IGNORE_DUPLICATED_THROWS" value="false" />
+ <option name="IGNORE_POINT_TO_ITSELF" value="false" />
+ <option name="myAdditionalJavadocTags" value="date" />
+ </inspection_tool>
+ </profile>
+</component>
\ No newline at end of file
Index: .idea/misc.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+><?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"ASMPluginConfiguration\">\n <asm skipDebug=\"false\" skipFrames=\"false\" skipCode=\"false\" expandFrames=\"false\" />\n <groovy codeStyle=\"LEGACY\" />\n </component>\n <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_1_7\" project-jdk-name=\"1.8\" project-jdk-type=\"JavaSDK\">\n <output url=\"file://$PROJECT_DIR$/build/classes\" />\n </component>\n <component name=\"ProjectType\">\n <option name=\"id\" value=\"Android\" />\n </component>\n</project>
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- .idea/misc.xml (revision 398e43b09b74ac1319d2bdb60e1bac0c018ce1ff)
+++ .idea/misc.xml (date 1611045041000)
@@ -4,7 +4,7 @@
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" />
</component>
- <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
Index: .idea/vcs.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- .idea/vcs.xml (date 1611044633000)
+++ .idea/vcs.xml (date 1611044633000)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="" vcs="Git" />
+ </component>
+</project>
\ No newline at end of file
Index: .idea/compiler.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- .idea/compiler.xml (date 1611045041000)
+++ .idea/compiler.xml (date 1611045041000)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="CompilerConfiguration">
+ <bytecodeTargetLevel target="1.8" />
+ </component>
+</project>
\ No newline at end of file
Index: .idea/gradle.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+><?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"GradleMigrationSettings\" migrationVersion=\"1\" />\n <component name=\"GradleSettings\">\n <option name=\"linkedExternalProjectsSettings\">\n <GradleProjectSettings>\n <option name=\"testRunner\" value=\"PLATFORM\" />\n <option name=\"distributionType\" value=\"DEFAULT_WRAPPED\" />\n <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n <option name=\"gradleJvm\" value=\"1.8\" />\n <option name=\"modules\">\n <set>\n <option value=\"$PROJECT_DIR$\" />\n <option value=\"$PROJECT_DIR$/app\" />\n <option value=\"$PROJECT_DIR$/foudations\" />\n <option value=\"$PROJECT_DIR$/foudations/mogo-passport\" />\n </set>\n </option>\n <option name=\"resolveModulePerSourceSet\" value=\"false\" />\n </GradleProjectSettings>\n </option>\n </component>\n</project>
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- .idea/gradle.xml (revision 398e43b09b74ac1319d2bdb60e1bac0c018ce1ff)
+++ .idea/gradle.xml (date 1611044633000)
@@ -17,6 +17,7 @@
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
+ <option name="useQualifiedModuleNames" value="true" />
</GradleProjectSettings>
</option>
</component>

View File

@@ -0,0 +1,4 @@
<changelist name="Uncommitted_changes_before_Update_at_1_19_21_6_39_PM_[Default_Changelist]" date="1611052761316" recycled="true" deleted="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_Update_at_1_19_21_6_39_PM_[Default_Changelist]/shelved.patch" />
<option name="DESCRIPTION" value="Uncommitted changes before Update at 1/19/21 6:39 PM [Default Changelist]" />
</changelist>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@@ -2,6 +2,7 @@
apply from: "config.gradle"
buildscript {
ext.kotlin_version = "1.3.72"
repositories {
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
@@ -17,6 +18,7 @@ buildscript {
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

1
foudations/mogo-httpdns/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1,44 @@
plugins {
id 'com.android.library'
id 'kotlin-android'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
minSdkVersion 19
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,24 @@
package com.mogo.cloud.httpdns
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.mogo.cloud.httpdns.test", appContext.packageName)
}
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.cloud.httpdns">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>

View File

@@ -0,0 +1,191 @@
package com.mogo.cloud.httpdns
import android.os.Handler
import android.os.HandlerThread
import android.os.Message
import android.util.ArrayMap
import com.mogo.cloud.httpdns.listener.IMogoHttpDns
import com.mogo.cloud.httpdns.listener.OnAddressChangedListener
import com.mogo.cloud.httpdns.util.ApiManager
import com.mogo.cloud.httpdns.util.L
import com.mogo.cloud.httpdns.util.NetWorkUtil
import java.util.*
import kotlin.collections.ArrayList
/**
* 1. 本地每15min查询一次
* 2. 网络状态发生变化时候重置15min轮询并查询一次
*
* @author tongchenfei
*/
internal class HttpDnsHelper(private val builder: MogoHttpDnsConfig) : Handler.Callback,IMogoHttpDns {
companion object {
const val HTTP_DNS_TYPE_HTTP = 0
const val HTTP_DNS_TYPE_WS = 1
const val HTTP_DNS_TYPE_IM = 2
private const val MSG_REQUEST_IP_PORT = 1001
private const val TAG = "HttpDnsHelper"
}
private val netWorkUtil = NetWorkUtil()
private var localConnectStateCache = false
private val workThread = HandlerThread("mogo-http-dns-work-thread")
private val handler: Handler
private var addressMap: Map<String, String>? = null
var addressChangedListener: OnAddressChangedListener? = null
private val apiManager: ApiManager
private var isInit = false
private var defaultUrl: String? = null
init {
L.isDebug = builder.showDebugLog()
defaultUrl = builder.getDefaultUrl()
L.d(TAG, "init===")
checkParams()
isInit = true
L.d(TAG, "params available, prepare to start check net status")
workThread.start()
handler = Handler(workThread.looper, this)
apiManager = ApiManager(builder.getSn()!!, builder.getEnv(), builder.getAppKey())
handler.sendEmptyMessageDelayed(MSG_REQUEST_IP_PORT, builder.getLoopCheckDelay())
netWorkUtil.registerStatusCallback(builder.getContext()!!) {
if (it && !localConnectStateCache) {
// 网络状态可用且本地记录的连接状态为false开始请求
handler.removeMessages(MSG_REQUEST_IP_PORT)
// 立即执行
handler.sendEmptyMessage(MSG_REQUEST_IP_PORT)
}
localConnectStateCache = it
}
}
private fun getHttpDnsAddressFromNet() {
val nAddress = apiManager.requestHttpDns(builder.getCurrentLocation()!!)
if (addressChangedListener == null) {
L.d(TAG, "addressChangeList is null")
}
if (addressMap == null) {
addressMap = nAddress
addressChangedListener?.onAddressChanged(addressMap)
} else if (nAddress != null) {
addressChangedListener?.onAddressChanged(mapDiff(nAddress, addressMap!!))
addressMap = nAddress
}
}
@Volatile
private var isRequest = false
private val requestCache = ArrayList<String>()
private val requestLock = Any()
override fun getHttpDnsAddress(type: Int, _host: String): String? {
val host = _host.toLowerCase(Locale.getDefault())
if (isInit) {
requestCache.add("$type-$host")
synchronized(requestLock) {
L.d(TAG, "getHttpDnsAddress: $type-$host \n thread: ${Thread.currentThread().name} isRequest: $isRequest")
if (!isRequest) {
isRequest = true
L.d(TAG, "prepare to get http dns from net thread: ${Thread.currentThread().name}")
getHttpDnsAddressFromNet()
}
}
addressMap?.let {
val builder = StringBuilder()
for (key in it.keys) {
builder.append(key).append(" : ").append(it[key]).append("\n")
}
L.d(TAG, "getHttpDnsAddress over $type-$host ${builder.toString()}")
requestCache.remove("$type-$host")
L.d(TAG, "requestCache.size: ${requestCache.size}")
if (requestCache.isEmpty()) {
isRequest = false
}
return if (it["$type-$host"] == null) {
defaultUrl ?: host
} else {
it["$type-$host"]
}
}
L.d(TAG, "getHttpDnsAddress over addressMap is null")
} else {
L.d(TAG, "not init over")
throw IllegalStateException("Http dns not init")
}
return defaultUrl ?: host
}
override fun getHttpDnsCachedAddress(type: Int, _host: String): String? {
val host = _host.toLowerCase(Locale.getDefault())
L.d(TAG, "getHttpDnsCachedAddress: $type-$host")
return addressMap?.get("$type-$host")
}
override fun getAllAddress(): Map<String, String>? {
return addressMap
}
override fun handleMessage(msg: Message): Boolean {
if (msg.what == MSG_REQUEST_IP_PORT) {
L.d(TAG, "http dns loop check")
if (isInit) {
// 网络接口请求
getHttpDnsAddressFromNet()
handler.sendEmptyMessageDelayed(MSG_REQUEST_IP_PORT, builder.getLoopCheckDelay())
} else {
L.d(TAG, "not init over")
}
return true
}
return false
}
override fun release() {
netWorkUtil.release()
}
private fun mapDiff(new: Map<String, String>, old: Map<String, String>): Map<String, String> {
val diff = ArrayMap<String, String>()
for (key in new.keys) {
if (old[key] == null) {
diff[key] = new[key]
} else if (old[key] != new[key]) {
diff[key] = new[key]
}
}
for (key in old.keys) {
if (!new.containsKey(key)) {
diff[key] = null
}
}
for (i in diff.keys) {
L.d(TAG, "diff key: $i")
}
return diff
}
private fun checkParams(): Boolean {
if (builder.getContext() == null) {
L.e(TAG, "no context")
throw IllegalArgumentException("can not find context in builder")
}
if (builder.getSn() == null) {
L.e(TAG, "no sn")
throw IllegalArgumentException("can not find sn in builder")
}
if (builder.getCurrentLocation() == null) {
L.e(TAG, "no current location")
throw IllegalArgumentException("can not find currentLocation in builder")
}
return true
}
}

View File

@@ -0,0 +1,52 @@
package com.mogo.cloud.httpdns
import com.mogo.cloud.httpdns.listener.IMogoHttpDns
import java.lang.IllegalStateException
object MogoHttpDnsClient : IMogoHttpDns {
private var httpDnsHelper:HttpDnsHelper? = null
fun init(config: MogoHttpDnsConfig) {
if(httpDnsHelper == null) {
httpDnsHelper = HttpDnsHelper(config)
}
}
/**
* 先从本地缓存中根据type和host获取ip:port如果本地缓存中没有再通过网络获取
*/
fun getHttpDnsAddressUseCacheIfNecessary(type: Int, _host: String):String?{
return getHttpDnsCachedAddress(type, _host) ?: return getHttpDnsAddress(type, _host)
}
override fun getHttpDnsAddress(type: Int, _host: String): String? {
if (httpDnsHelper == null) {
throw IllegalStateException("MogoHttpDnsClient init error")
}
return httpDnsHelper!!.getHttpDnsAddress(type,_host)
}
override fun getHttpDnsCachedAddress(type: Int, _host: String): String? {
if (httpDnsHelper == null) {
throw IllegalStateException("MogoHttpDnsClient init error")
}
return httpDnsHelper!!.getHttpDnsCachedAddress(type, _host)
}
override fun getAllAddress(): Map<String, String>? {
if (httpDnsHelper == null) {
throw IllegalStateException("MogoHttpDnsClient init error")
}
return httpDnsHelper!!.getAllAddress()
}
override fun release() {
if (httpDnsHelper == null) {
throw IllegalStateException("MogoHttpDnsClient init error")
}
httpDnsHelper!!.release()
}
}

View File

@@ -0,0 +1,110 @@
package com.mogo.cloud.httpdns
import android.content.Context
import com.mogo.cloud.httpdns.listener.IHttpDnsCurrentLocation
class MogoHttpDnsConfig {
companion object{
/**
* 研发环境
*/
const val HTTP_DNS_ENV_DEV = 1
/**
* 测试环境
*/
const val HTTP_DNS_ENV_QA = 2
/**
* 演示环境
*/
const val HTTP_DNS_ENV_DEMO = 4
/**
* 线上环境
*/
const val HTTP_DNS_ENV_RELEASE = 3
}
private var mSn: String? = null
private var mCurrentLocation: IHttpDnsCurrentLocation? = null
private var mShowDebugLog: Boolean = false
private var mLoopCheckDelay: Long = 15 * 60 * 1000
private var mContext: Context? = null
private var mEnv = HTTP_DNS_ENV_RELEASE
private var mDefaultUrl:String? = null
private var mAppKey:String? = null
fun setContext(context: Context): MogoHttpDnsConfig {
mContext = context
return this
}
fun getContext(): Context? {
return mContext
}
fun setSn(sn: String): MogoHttpDnsConfig {
mSn = sn
return this
}
fun getSn(): String? {
return mSn
}
fun setShowDebugLog(showDebugLog: Boolean): MogoHttpDnsConfig {
mShowDebugLog = showDebugLog
return this
}
fun showDebugLog(): Boolean {
return mShowDebugLog
}
fun setLoopCheckDelay(loopCheckDelay: Long): MogoHttpDnsConfig {
mLoopCheckDelay = loopCheckDelay
return this
}
fun getLoopCheckDelay(): Long {
return mLoopCheckDelay
}
fun setCurrentLocation(currentLocation: IHttpDnsCurrentLocation): MogoHttpDnsConfig {
mCurrentLocation = currentLocation
return this
}
fun getCurrentLocation(): IHttpDnsCurrentLocation? {
return mCurrentLocation
}
fun setEnv(env:Int):MogoHttpDnsConfig{
mEnv = env
return this
}
fun getEnv():Int{
return mEnv
}
fun setDefaultUrl(defaultUrl:String):MogoHttpDnsConfig{
mDefaultUrl = defaultUrl
return this
}
fun getDefaultUrl():String?{
return mDefaultUrl
}
fun setAppKey(appKey: String): MogoHttpDnsConfig {
mAppKey = appKey
return this
}
fun getAppKey():String{
return mAppKey ?: ""
}
}

View File

@@ -0,0 +1,8 @@
package com.mogo.cloud.httpdns.bean
/**
* httpDns需要的定位信息需要使用高德定位的经纬度坐标和cityCode
*
* @author tongchenfei
*/
data class HttpDnsSimpleLocation(val cityCode:String,val lat:Double,val lon:Double)

View File

@@ -0,0 +1,7 @@
package com.mogo.cloud.httpdns.listener
import com.mogo.cloud.httpdns.bean.HttpDnsSimpleLocation
interface IHttpDnsCurrentLocation {
fun getCurrentLocation(): HttpDnsSimpleLocation?
}

View File

@@ -0,0 +1,38 @@
package com.mogo.cloud.httpdns.listener
import com.mogo.cloud.httpdns.HttpDnsHelper.Companion.HTTP_DNS_TYPE_HTTP
interface IMogoHttpDns {
/**
* 根据类型和host获取IP直接通过网络请求获取全部路由表
* 同时多线程多次请求会忽略部分网络请求,一定程度减少接口请求次数
*
* @param type [HTTP_DNS_TYPE_HTTP]用于请求http接口
* [HTTP_DNS_TYPE_WS]用于webSocket长连接
* 若增加新类型,可自行设置
* @return 类型对应的ip:port不带协议头以及path请自行补齐
* 特别注意若此type没有对应的ip:port本方法会返回null
*/
fun getHttpDnsAddress(type: Int, _host: String): String?
/**
* 根据类型和host获取本地cache的路由表
*
* @param type [HTTP_DNS_TYPE_HTTP]用于请求http接口
* [HTTP_DNS_TYPE_WS]用于webSocket长连接
* 若增加新类型,可自行设置
*
* @return 类型对应的ip:port不带协议头以及path请自行补齐
* 特别注意若此type没有对应的ip:port本方法会返回null
*/
fun getHttpDnsCachedAddress(type: Int, _host: String): String?
/**
* 获取全部路由表
*
* @return 返回本地缓存全部路由表如果没有则返回null
*/
fun getAllAddress(): Map<String, String>?
fun release()
}

View File

@@ -0,0 +1,5 @@
package com.mogo.cloud.httpdns.listener
interface OnAddressChangedListener {
fun onAddressChanged(address: Map<String, String>?)
}

View File

@@ -0,0 +1,83 @@
package com.mogo.cloud.httpdns.util
import android.util.ArrayMap
import com.mogo.cloud.httpdns.listener.IHttpDnsCurrentLocation
import org.json.JSONObject
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
import java.util.*
private const val TAG = "ApiManager"
/**
* 接口请求管理类
*
* @author tongchenfei
*/
class ApiManager(private val sn:String,private val env:Int,private val appKey:String) {
fun requestHttpDns(_location: IHttpDnsCurrentLocation):Map<String,String>? {
val location = _location.getCurrentLocation() ?: return null
var client: HttpURLConnection? = null
var bufferedReader: BufferedReader? = null
try {
client =
URL("http://dzt.zhidaozhixing.com/yycp-httpdns-service/api/httpDns/getIpAndPort").openConnection() as HttpURLConnection
client.requestMethod = "POST"
client.doInput = true
client.doOutput = true
client.useCaches = false
client.setRequestProperty("Content-type", "application/json")
client.setRequestProperty("Charset", "UTF-8")
client.setRequestProperty("app-key", appKey)
client.readTimeout = 1000
client.connectTimeout = 1000
client.connect()
val params =
"{\"sn\":\"$sn\",\"cityCode\":\"${location.cityCode}\",\"lat\":${location.lat},\"lon\":${location.lon},\"env\":$env}"
L.d(TAG, "params: $params")
client.outputStream.write(params.toByteArray())
client.outputStream.flush()
client.outputStream.close()
L.d(TAG, "response: ${client.responseCode}")
bufferedReader = BufferedReader(InputStreamReader(client.inputStream))
val builder = StringBuilder()
while (true) {
val line = bufferedReader.readLine()
if (line != null) {
builder.append(line)
} else {
break
}
}
val msg = builder.toString()
bufferedReader.close()
client.disconnect()
L.d(TAG, msg)
val json = JSONObject(msg)
val jsonArray = json.optJSONObject("result")?.optJSONArray("urls")
jsonArray?.apply {
val map = ArrayMap<String, String>(length())
for (i in 0 until length()) {
val item = optJSONObject(i)
val type = item.optInt("type")
val url = item.optString("url")
val host = item.optString("domain").toLowerCase(Locale.getDefault())
map["$type-$host"] = url
}
return map
}
} catch (e: Exception) {
e.printStackTrace()
L.e(TAG, e.message ?: "exception===")
bufferedReader?.close()
client?.disconnect()
}
return null
}
}

View File

@@ -0,0 +1,23 @@
package com.mogo.cloud.httpdns.util
import android.util.Log
/**
* 简单实现日志工具类
*
* @author tongchenfei
*/
object L {
var isDebug = true
fun d(tag: String, msg: String) {
if (isDebug) {
Log.d(tag, msg)
// println(msg)
}
}
fun e(tag: String, msg: String) {
Log.e(tag, msg)
// println(msg)
}
}

View File

@@ -0,0 +1,56 @@
package com.mogo.cloud.httpdns.util
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.ConnectivityManager
private const val TAG = "NetWorkUtil"
/**
* 网络状态工具类
* 监听和获取网络状态
*
* @author tongchenfei
*/
class NetWorkUtil {
private var statusCallback: ((Boolean) -> Unit)? = null
private var connectivityManager: ConnectivityManager? = null
private var context: Context? = null
fun registerStatusCallback(context: Context, statusCallback: (Boolean) -> Unit) {
this.statusCallback = statusCallback
this.context = context
connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val intentFilter = IntentFilter()
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE")
context.registerReceiver(receiver, intentFilter)
}
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
connectivityManager?.apply {
if (activeNetworkInfo == null) {
L.d(TAG, "activityNetworkInfo is null")
statusCallback?.invoke(false)
} else {
if (activeNetworkInfo!!.type == -1) {
L.d(TAG, "activityNetworkInfo.type == -1")
statusCallback?.invoke(false)
} else {
L.d(TAG, "activityNetworkInfo.type: ${activeNetworkInfo!!.type}")
statusCallback?.invoke(true)
}
}
}
}
}
fun release() {
context?.unregisterReceiver(receiver)
}
}

View File

@@ -0,0 +1,17 @@
package com.mogo.cloud.httpdns
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@@ -1,3 +1,4 @@
include ':foudations:mogo-httpdns'
include ':foudations:mogo-passport'
include ':app'
rootProject.name = "MoGoAiCloudSdk"