feat(chat): implement AiChatRepository for SSE streaming
This commit is contained in:
parent
f93c7c3e43
commit
fcf63c6175
|
|
@ -0,0 +1,55 @@
|
|||
package com.stand.standapp.ui.chat.repo
|
||||
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.Response
|
||||
import okhttp3.sse.EventSource
|
||||
import okhttp3.sse.EventSourceListener
|
||||
import okhttp3.sse.EventSources
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class AiChatRepository {
|
||||
// 根据后端实际情况修改,模拟器访问本地后端用 10.0.2.2
|
||||
private val backendUrl = "http://10.0.2.2:8080/api/chat/stream"
|
||||
|
||||
private val client = OkHttpClient.Builder()
|
||||
.readTimeout(0, TimeUnit.MILLISECONDS) // SSE 需要关闭读取超时
|
||||
.build()
|
||||
|
||||
fun streamChat(message: String): Flow<String> = callbackFlow {
|
||||
val json = """{"message": "$message"}"""
|
||||
val request = Request.Builder()
|
||||
.url(backendUrl)
|
||||
.post(json.toRequestBody("application/json".toMediaType()))
|
||||
.header("Accept", "text/event-stream")
|
||||
.build()
|
||||
|
||||
val listener = object : EventSourceListener() {
|
||||
override fun onEvent(eventSource: EventSource, id: String?, type: String?, data: String) {
|
||||
// 收到后端推送的数据块
|
||||
trySend(data)
|
||||
}
|
||||
|
||||
override fun onFailure(eventSource: EventSource, t: Throwable?, response: Response?) {
|
||||
Timber.e(t, "SSE Connection failed")
|
||||
close(t) // 结束流
|
||||
}
|
||||
|
||||
override fun onClosed(eventSource: EventSource) {
|
||||
close() // 正常结束
|
||||
}
|
||||
}
|
||||
|
||||
val eventSource = EventSources.createFactory(client).newEventSource(request, listener)
|
||||
|
||||
awaitClose {
|
||||
eventSource.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue