...
This commit is contained in:
parent
7fa1c36355
commit
c5bc3f9bf0
@ -20,6 +20,7 @@ dependencies {
|
||||
implementation(compose.desktop.currentOs)
|
||||
implementation(compose.material)
|
||||
implementation(compose.materialIconsExtended)
|
||||
implementation("io.ktor:ktor-client-okhttp-jvm:2.3.11")
|
||||
|
||||
// Ktor (Network)
|
||||
val ktorVersion = "2.3.11"
|
||||
|
||||
@ -149,6 +149,7 @@ fun main() = application {
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
AutoTradingManager.startAutoDiscoveryLoop()
|
||||
KisWebSocketManager.onExecutionReceived = AutoTradingManager.onExecutionReceived
|
||||
KisWebSocketManager.connect()
|
||||
}
|
||||
|
||||
if (config.modelPath.isNotEmpty()) {
|
||||
|
||||
@ -2,7 +2,14 @@ package network
|
||||
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.cio.CIO
|
||||
import io.ktor.client.engine.okhttp.OkHttp
|
||||
import io.ktor.client.engine.config
|
||||
import io.ktor.client.plugins.HttpTimeout
|
||||
import io.ktor.client.plugins.websocket.*
|
||||
import io.ktor.client.engine.cio.*
|
||||
import io.ktor.client.engine.okhttp.*
|
||||
import io.ktor.client.plugins.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.websocket.*
|
||||
import kotlinx.coroutines.*
|
||||
@ -12,21 +19,55 @@ import kotlinx.serialization.json.jsonPrimitive
|
||||
import model.KisSession
|
||||
import model.RealTimeTrade
|
||||
import util.AesCrypto
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
object KisWebSocketManager {
|
||||
private val client = HttpClient {
|
||||
|
||||
val os = System.getProperty("os.name").lowercase()
|
||||
val arch = System.getProperty("os.arch").lowercase()
|
||||
val isWin = os.contains("win")
|
||||
|
||||
private val client = HttpClient(if(isWin){ OkHttp } else { CIO }) {
|
||||
install(WebSockets) {
|
||||
pingInterval = 20_000 // 20초마다 표준 웹소켓 핑 전송 (서버-클라이언트 연결 유지 도움)
|
||||
pingInterval = 20_000
|
||||
}
|
||||
install(HttpTimeout) {
|
||||
requestTimeoutMillis = 30_000 // 전체 요청 시간
|
||||
connectTimeoutMillis = 10_000 // 서버 연결 시간
|
||||
socketTimeoutMillis = 30_000 // 데이터 패킷 간격 시간
|
||||
}
|
||||
|
||||
// 엔진별 상세 설정 (config 대신 해당 엔진 명칭 사용)
|
||||
if (isWin) {
|
||||
engine {
|
||||
// OkHttp 환경 특화: 윈도우 네트워크 유휴 상태 방지
|
||||
this as OkHttpConfig
|
||||
config {
|
||||
retryOnConnectionFailure(true)
|
||||
connectTimeout(15, TimeUnit.SECONDS)
|
||||
readTimeout(0, TimeUnit.SECONDS) // 무제한 대기
|
||||
}
|
||||
}
|
||||
} else {
|
||||
engine {
|
||||
// CIO 엔진 설정
|
||||
this as CIOEngineConfig
|
||||
endpoint {
|
||||
connectTimeout = 15_000
|
||||
requestTimeout = 30_000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var session: DefaultClientWebSocketSession? = null
|
||||
private val isConnected = AtomicBoolean(false)
|
||||
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
private var connectJob: Job? = null
|
||||
|
||||
// 콜백 리스너
|
||||
var onPriceUpdate: ((RealTimeTrade) -> Unit)? = null
|
||||
|
||||
var onExecutionReceived: ((String, String, String, String, Boolean) -> Unit)? = null
|
||||
|
||||
suspend fun connect() {
|
||||
@ -72,7 +113,7 @@ object KisWebSocketManager {
|
||||
}
|
||||
|
||||
|
||||
// private val _currentPrice = mutableStateOf("0")
|
||||
// private val _currentPrice = mutableStateOf("0")
|
||||
private val currentPrice = androidx.compose.runtime.mutableStateMapOf<String, String>()
|
||||
// val currentPrice = _currentPrice
|
||||
|
||||
|
||||
@ -164,15 +164,20 @@ fun SettingsScreen(onAuthSuccess: () -> Unit) {
|
||||
scope.launch {
|
||||
var retryCount = 0
|
||||
val maxRetries = 3
|
||||
val retryDelay = 90_000L // 1분 30초
|
||||
val totalDelaySeconds = 90 // 1분 30초 = 90초
|
||||
var isAuthCompleted = false
|
||||
|
||||
while (retryCount <= maxRetries && !isAuthCompleted) {
|
||||
// 재시도 시 대기 및 카운트다운 표시
|
||||
if (retryCount > 0) {
|
||||
statusMessage = "⏳ 인증 재시도 중... (${retryCount}/${maxRetries}) - 1분 30초 후 재시작"
|
||||
delay(retryDelay)
|
||||
for (secondsLeft in totalDelaySeconds downTo 1) {
|
||||
statusMessage = "⚠️ 인증 실패. ${secondsLeft}초 후 자동으로 다시 시도합니다. (시도 ${retryCount}/${maxRetries})"
|
||||
delay(1000L) // 1초 대기
|
||||
}
|
||||
}
|
||||
|
||||
statusMessage = if (retryCount == 0) "⏳ 인증 시도 중..." else "⏳ ${retryCount}차 재시도 중..."
|
||||
|
||||
// 1. 설정값 저장
|
||||
KisSession.config = config
|
||||
DatabaseFactory.saveConfig(config)
|
||||
@ -194,9 +199,8 @@ fun SettingsScreen(onAuthSuccess: () -> Unit) {
|
||||
retryCount++
|
||||
if (retryCount > maxRetries) {
|
||||
statusMessage = "❌ 인증 실패. 3회 재시도 후 중단되었습니다. 키 정보를 확인하세요."
|
||||
} else {
|
||||
statusMessage = "⚠️ 인증 실패. 잠시 후 자동으로 다시 시도합니다. (시도 $retryCount)"
|
||||
}
|
||||
// 다음 루프에서 카운트다운 진입
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user