This commit is contained in:
tursom 2021-05-11 15:14:09 +08:00
parent 546f3b7a8e
commit 993de664d9
11 changed files with 72 additions and 44 deletions

View File

@ -1,7 +1,5 @@
package cn.tursom.core.clone
package cn.tursom.core
import cn.tursom.core.Unsafe
import cn.tursom.core.uncheckedCast
import java.util.concurrent.ConcurrentHashMap
import kotlin.reflect.KClass

View File

@ -66,11 +66,8 @@ object Parser {
else -> {
if (yaml !is Map<*, *>) return null
val instance = try {
clazz.newInstance()
} catch (e: Exception) {
unsafe.allocateInstance(clazz)
}
val instance = InstantAllocator[clazz]
val fields = clazz.declaredFields
fields.forEach {
if ((it.modifiers and (Modifier.STATIC or Modifier.TRANSIENT)) != 0) return@forEach

View File

@ -1,11 +1,8 @@
package cn.tursom.core.clone
import cn.tursom.core.Unsafe
import cn.tursom.core.allMemberProperties
import cn.tursom.core.*
import cn.tursom.core.datastruct.KPropertyValueMap
import cn.tursom.core.datastruct.SoftArrayMap
import cn.tursom.core.unaryPlus
import cn.tursom.core.uncheckedCast
import cn.tursom.log.impl.Slf4jImpl
import java.util.concurrent.ConcurrentHashMap
import kotlin.collections.component1

View File

@ -106,13 +106,15 @@ class WebSocketClient(
//handler.handshakeFuture().sync()
}
fun close(reasonText: String? = null) {
fun close(reasonText: String? = null): ChannelFuture? {
if (reasonText == null) {
ch?.writeAndFlush(CloseWebSocketFrame())
} else {
ch?.writeAndFlush(CloseWebSocketFrame(WebSocketCloseStatus.NORMAL_CLOSURE, reasonText))
}
ch?.closeFuture()?.sync()
ch?.close()
return ch?.closeFuture()
//ch?.closeFuture()?.sync()
}
fun write(text: String): ChannelFuture {

View File

@ -8,7 +8,7 @@ import io.netty.handler.codec.http.websocketx.*
class WebSocketClientChannelHandler(
val client: WebSocketClient,
val handler: WebSocketHandler,
autoRelease: Boolean = true,
private val autoRelease: Boolean = true,
) : SimpleChannelInboundHandler<WebSocketFrame>(autoRelease) {
override fun channelInactive(ctx: ChannelHandlerContext) {
@ -25,7 +25,11 @@ class WebSocketClientChannelHandler(
is BinaryWebSocketFrame -> handler.readMessage(client, msg)
is PingWebSocketFrame -> handler.readPing(client, msg)
is PongWebSocketFrame -> handler.readPong(client, msg)
is CloseWebSocketFrame -> ch.close()
is CloseWebSocketFrame -> {
if (!autoRelease) while (msg.refCnt() != 0) msg.release()
ch.close()
}
else -> if (!autoRelease) while (msg.refCnt() != 0) msg.release()
}
}
}

View File

@ -1,6 +1,6 @@
package cn.tursom.database
import cn.tursom.core.clone.InstantAllocator
import cn.tursom.core.InstantAllocator
import cn.tursom.core.getClassByPackage
import cn.tursom.core.uncheckedCast
import me.liuwj.ktorm.schema.BaseTable

View File

@ -0,0 +1,8 @@
package cn.tursom.web.router
import java.lang.reflect.Method
data class MappedMethod(
val method: Method,
val aspect: List<WebAspect>
)

View File

@ -34,7 +34,7 @@ import java.util.concurrent.atomic.AtomicInteger
*/
@Suppress("MemberVisibilityCanBePrivate", "unused")
open class RoutedHttpHandler(
target: Any? = null,
vararg target: Any,
val routerMaker: () -> Router<Pair<Any?, (HttpContent) -> Any?>> = { SimpleRouter() }
) : HttpHandler<HttpContent, ExceptionContent> {
protected val router: Router<Pair<Any?, (HttpContent) -> Any?>> = routerMaker()
@ -52,7 +52,11 @@ open class RoutedHttpHandler(
init {
@Suppress("LeakingThis")
addRouter(target ?: this)
if ((target.isEmpty())) {
addRouter(this)
} else {
target.forEach(::addRouter)
}
}
override fun handle(content: HttpContent) {
@ -150,30 +154,30 @@ open class RoutedHttpHandler(
Unit::class.java -> lambda { content: HttpContent -> method(obj, content) }
else -> when {
method.getAnnotation(Html::class.java) != null -> lambda { content: HttpContent ->
method(obj, content)?.let { result -> finishHtml(result, content, doLog) }
finishHtml(method(obj, content), content, doLog)
}
method.getAnnotation(Text::class.java) != null -> lambda { content: HttpContent ->
method(obj, content)?.let { result -> finishText(result, content, doLog) }
finishText(method(obj, content), content, doLog)
}
method.getAnnotation(Json::class.java) != null -> lambda { content: HttpContent ->
method(obj, content)?.let { result -> finishJson(result, content, doLog) }
finishJson(method(obj, content), content, doLog)
}
else -> lambda { content: HttpContent ->
method(obj, content)?.let { result -> autoReturn(method, result, content, doLog) }
autoReturn(method, method(obj, content), content, doLog)
}
}
} else when {
method.getAnnotation(Html::class.java) != null -> lambda { content: HttpContent ->
method(obj)?.let { result -> finishHtml(result, content, doLog) }
finishHtml(method(obj), content, doLog)
}
method.getAnnotation(Text::class.java) != null -> lambda { content: HttpContent ->
method(obj)?.let { result -> finishText(result, content, doLog) }
finishText(method(obj), content, doLog)
}
method.getAnnotation(Json::class.java) != null -> lambda { content: HttpContent ->
method(obj)?.let { result -> finishJson(result, content, doLog) }
finishJson(method(obj), content, doLog)
}
else -> lambda { content: HttpContent ->
method(obj)?.let { result -> autoReturn(method, result, content, doLog) }
autoReturn(method, method(obj), content, doLog)
}
}).let {
if (method.getAnnotation(BlockHandler::class.java) != null) lambda { content ->
@ -282,6 +286,7 @@ open class RoutedHttpHandler(
}.repeatUntil({ it.contains("//") }) { it.replace(slashRegex, "/") }
fun autoReturn(method: Method, result: Any?, content: HttpContent, doLog: Boolean? = null) {
if (content.finished || result is Unit) return
method.getAnnotation(ContextType::class.java)?.let {
content.setContextType(it.type.value)
log?.debug("{}: autoReturn context type auto set to {}({})", content.remoteAddress, it.type.key, it.type.value)
@ -290,6 +295,7 @@ open class RoutedHttpHandler(
}
fun autoReturn(result: Any?, content: HttpContent, doLog: Boolean = true) {
if (content.finished || result is Unit) return
if (doLog) log?.debug("{}: autoReturn: {}", content.remoteAddress, result)
result ?: return
when (result) {
@ -312,6 +318,7 @@ open class RoutedHttpHandler(
}
fun finishHtml(result: Any?, content: HttpContent, doLog: Boolean = true) {
if (content.finished || result is Unit) return
if (doLog) log?.debug("{} finishHtml {}", content.remoteAddress, result)
result ?: return
when (result) {
@ -330,6 +337,7 @@ open class RoutedHttpHandler(
}
fun finishText(result: Any?, content: HttpContent, doLog: Boolean = true) {
if (content.finished || result is Unit) return
if (doLog) log?.debug("{} finishText {}", content.remoteAddress, result)
result ?: return
when (result) {
@ -348,6 +356,7 @@ open class RoutedHttpHandler(
}
fun finishJson(result: Any?, content: HttpContent, doLog: Boolean = true) {
if (content.finished || result is Unit) return
if (doLog) log?.debug("{} finishJson {}", content.remoteAddress, result)
result ?: return
when (result) {

View File

@ -0,0 +1,5 @@
package cn.tursom.web.router
interface WebAspect {
}

View File

@ -17,7 +17,7 @@ import kotlin.reflect.jvm.jvmErasure
@Suppress("ProtectedInFinal", "unused", "MemberVisibilityCanBePrivate")
open class AsyncRoutedHttpHandler(
target: Any? = null,
vararg target: Any,
routerMaker: () -> Router<Pair<Any?, (HttpContent) -> Any?>> = { SimpleRouter() },
val asyncRouterMaker: () -> Router<Pair<Any?, suspend (HttpContent) -> Unit>> = { SimpleRouter() }
) : RoutedHttpHandler(target, routerMaker) {
@ -60,7 +60,10 @@ open class AsyncRoutedHttpHandler(
}
}
fun getAsyncHandler(method: String, route: String): Pair<Pair<Any?, suspend (HttpContent) -> Unit>?, List<Pair<String, String>>> {
fun getAsyncHandler(
method: String,
route: String
): Pair<Pair<Any?, suspend (HttpContent) -> Unit>?, List<Pair<String, String>>> {
val safeRoute = safeRoute(route)
val router = getAsyncRouter(method)[safeRoute]
return if (router.first != null) router else this.asyncRouter[safeRoute]
@ -110,21 +113,26 @@ open class AsyncRoutedHttpHandler(
}
@Suppress("UNCHECKED_CAST")
fun addRouter(obj: Any, method: KCallable<*>, route: String, router: Router<Pair<Any?, suspend (HttpContent) -> Unit>>) {
fun addRouter(
obj: Any,
method: KCallable<*>,
route: String,
router: Router<Pair<Any?, suspend (HttpContent) -> Unit>>
) {
val doLog = method.doLog
router[safeRoute(route)] = if (method.parameters.size == 1) {
obj to when {
method.findAnnotation<Html>() != null -> { content ->
(method as suspend Any.() -> Any?)(obj)?.let { result -> finishHtml(result, content, doLog) }
finishHtml((method as suspend Any.() -> Any?)(obj), content, doLog)
}
method.findAnnotation<Text>() != null -> { content ->
(method as suspend Any.() -> Any?)(obj)?.let { result -> finishText(result, content, doLog) }
finishText((method as suspend Any.() -> Any?)(obj), content, doLog)
}
method.findAnnotation<Json>() != null -> { content ->
(method as suspend Any.() -> Any?)(obj)?.let { result -> finishJson(result, content, doLog) }
finishJson((method as suspend Any.() -> Any?)(obj), content, doLog)
}
else -> { content ->
(method as suspend Any.() -> Any?)(obj)?.let { result -> autoReturn(method, result, content, doLog) }
autoReturn(method, (method as suspend Any.() -> Any?)(obj), content, doLog)
}
}
} else obj to when (method.returnType.jvmErasure.java) {
@ -133,16 +141,16 @@ open class AsyncRoutedHttpHandler(
Unit::class.java -> { content -> (method as suspend Any.(HttpContent) -> Unit)(obj, content) }
else -> when {
method.findAnnotation<Html>() != null -> { content ->
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishHtml(result, content, doLog) }
finishHtml((method as suspend Any.(HttpContent) -> Any?)(obj, content), content, doLog)
}
method.findAnnotation<Text>() != null -> { content ->
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishText(result, content, doLog) }
finishText((method as suspend Any.(HttpContent) -> Any?)(obj, content), content, doLog)
}
method.findAnnotation<Json>() != null -> { content ->
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> finishJson(result, content, doLog) }
finishJson((method as suspend Any.(HttpContent) -> Any?)(obj, content), content, doLog)
}
else -> { content ->
(method as suspend Any.(HttpContent) -> Any?)(obj, content)?.let { result -> autoReturn(method, result, content, doLog) }
autoReturn(method, (method as suspend Any.(HttpContent) -> Any?)(obj, content), content, doLog)
}
}
}

View File

@ -4,12 +4,12 @@ plugins {
}
dependencies {
implementation(project(":ts-core"))
implementation(project(":ts-core:ts-buffer"))
implementation(project(":ts-core:ts-log"))
implementation(project(":ts-web"))
implementation(group = "io.netty", name = "netty-all", version = "4.1.43.Final")
implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.29")
api(project(":ts-core"))
api(project(":ts-core:ts-buffer"))
api(project(":ts-core:ts-log"))
api(project(":ts-web"))
api(group = "io.netty", name = "netty-all", version = "4.1.43.Final")
api(group = "org.slf4j", name = "slf4j-api", version = "1.7.29")
}
@kotlin.Suppress("UNCHECKED_CAST")