From 2eaa295ad69bd7d24e0b595725f46d6a4ae7cf83 Mon Sep 17 00:00:00 2001 From: Xwite <1797350009@qq.com> Date: Mon, 27 Mar 2023 09:23:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=90=9C=E7=B4=A2=E4=B9=A6?= =?UTF-8?q?=E7=B1=8D=E6=B7=BB=E5=8A=A0=E4=B9=A6=E7=B1=8Dapi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/api/controller/BookController.kt | 2 +- .../main/java/io/legado/app/web/HttpServer.kt | 9 +- .../java/io/legado/app/web/WebSocketServer.kt | 3 + .../app/web/socket/BookSearchWebSocket.kt | 92 +++++++++++++++++++ 4 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt diff --git a/app/src/main/java/io/legado/app/api/controller/BookController.kt b/app/src/main/java/io/legado/app/api/controller/BookController.kt index a1244208e..38bcd35ed 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookController.kt @@ -200,7 +200,7 @@ object BookController { fun saveBook(postData: String?): ReturnData { val returnData = ReturnData() GSON.fromJsonObject(postData).getOrNull()?.let { book -> - appDb.bookDao.update(book) + appDb.bookDao.insert(book) AppWebDav.uploadBookProgress(book) return returnData.setData("") } diff --git a/app/src/main/java/io/legado/app/web/HttpServer.kt b/app/src/main/java/io/legado/app/web/HttpServer.kt index 71b915410..b5f4183c4 100644 --- a/app/src/main/java/io/legado/app/web/HttpServer.kt +++ b/app/src/main/java/io/legado/app/web/HttpServer.kt @@ -1,7 +1,6 @@ package io.legado.app.web import android.graphics.Bitmap -import com.google.gson.Gson import fi.iki.elonen.NanoHTTPD import io.legado.app.api.ReturnData import io.legado.app.api.controller.BookController @@ -9,13 +8,11 @@ import io.legado.app.api.controller.BookSourceController import io.legado.app.api.controller.ReplaceRuleController import io.legado.app.api.controller.RssSourceController import io.legado.app.service.WebService -import io.legado.app.utils.FileUtils -import io.legado.app.utils.externalFiles +import io.legado.app.utils.* import io.legado.app.web.utils.AssetsWeb import splitties.init.appCtx import java.io.* - class HttpServer(port: Int) : NanoHTTPD(port) { private val assetsWeb = AssetsWeb("web") @@ -100,7 +97,7 @@ class HttpServer(port: Int) : NanoHTTPD(port) { ) } else { try { - newFixedLengthResponse(Gson().toJson(returnData)) + newFixedLengthResponse(GSON.toJson(returnData)) } catch (e: OutOfMemoryError) { val path = FileUtils.getPath( appCtx.externalFiles, @@ -109,7 +106,7 @@ class HttpServer(port: Int) : NanoHTTPD(port) { ) val file = FileUtils.createFileIfNotExist(path) BufferedWriter(FileWriter(file)).use { - Gson().toJson(returnData, it) + GSON.toJson(returnData, it) } val fis = FileInputStream(file) newFixedLengthResponse( diff --git a/app/src/main/java/io/legado/app/web/WebSocketServer.kt b/app/src/main/java/io/legado/app/web/WebSocketServer.kt index 3e95c2101..fd130ae34 100644 --- a/app/src/main/java/io/legado/app/web/WebSocketServer.kt +++ b/app/src/main/java/io/legado/app/web/WebSocketServer.kt @@ -16,6 +16,9 @@ class WebSocketServer(port: Int) : NanoWSD(port) { "/rssSourceDebug" -> { RssSourceDebugWebSocket(handshake) } + "/searchBook" -> { + BookSearchWebSocket(handshake) + } else -> null } } diff --git a/app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt b/app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt new file mode 100644 index 000000000..18e6b1e11 --- /dev/null +++ b/app/src/main/java/io/legado/app/web/socket/BookSearchWebSocket.kt @@ -0,0 +1,92 @@ +package io.legado.app.web.socket + +import fi.iki.elonen.NanoHTTPD +import fi.iki.elonen.NanoWSD +import io.legado.app.R +import io.legado.app.data.entities.SearchBook +import io.legado.app.help.config.AppConfig +import io.legado.app.model.webBook.SearchModel +import io.legado.app.ui.book.search.SearchScope +import io.legado.app.utils.* +import kotlinx.coroutines.* +import kotlinx.coroutines.Dispatchers.IO +import splitties.init.appCtx + +import java.io.IOException + +class BookSearchWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) : + NanoWSD.WebSocket(handshakeRequest), + CoroutineScope by MainScope(), + SearchModel.CallBack { + + private val normalClosure = NanoWSD.WebSocketFrame.CloseCode.NormalClosure + private val searchModel = SearchModel(this, this) + + private const val SEARCH_FINISH = "Search finish" + + override fun onOpen() { + launch(IO) { + kotlin.runCatching { + while (isOpen) { + ping("ping".toByteArray()) + delay(30000) + } + } + } + } + + override fun onClose( + code: NanoWSD.WebSocketFrame.CloseCode, + reason: String, + initiatedByRemote: Boolean + ) { + cancel() + searchModel.close() + } + + override fun onMessage(message: NanoWSD.WebSocketFrame) { + launch(IO) { + kotlin.runCatching { + if (!message.textPayload.isJson()) { + send("数据必须为Json格式") + close(normalClosure, SEARCH_FINISH, false) + return@launch + } + val searchMap = + GSON.fromJsonObject>(message.textPayload).getOrNull() + if (searchMap != null) { + val key = searchMap["key"] + if (key.isNullOrBlank()) { + send(appCtx.getString(R.string.cannot_empty)) + close(normalClosure, SEARCH_FINISH, false) + return@launch + } + viewModel.search(System.currentTimeMillis(), key) + } + } + } + } + + override fun onPong(pong: NanoWSD.WebSocketFrame) { + + } + + override fun onException(exception: IOException) { + + } + + override fun getSearchScope(): SearchScope = SearchScope(AppConfig.searchScope) + + override fun onSearchStart() { + + } + + override fun onSearchSuccess(searchBooks: ArrayList) { + send(GSON.toJson(searchBooks)) + } + + override fun onSearchFinish(isEmpty: Boolean) = close(normalClosure, SEARCH_FINISH, false) + + override fun onSearchCancel(exception: Exception? = null) = close(normalClosure, exception?.toString() ?: SEARCH_FINISH, false) + +}