Procházet zdrojové kódy

faster speed with full socket

herlanS_ před 4 roky
rodič
revize
a9b090c574

+ 73 - 4
src/main/kotlin/co/id/datacomsolusindo/ipphonebridge/BridgeFIlter.kt

@@ -8,8 +8,10 @@ import org.springframework.context.annotation.Configuration
 import org.springframework.core.Ordered
 import org.springframework.core.annotation.Order
 import org.springframework.core.io.ResourceLoader
+import org.springframework.http.HttpHeaders
 import org.springframework.http.HttpMethod
 import org.springframework.http.HttpStatus
+import org.springframework.messaging.handler.annotation.DestinationVariable
 import org.springframework.messaging.handler.annotation.MessageMapping
 import org.springframework.messaging.handler.annotation.SendTo
 import org.springframework.messaging.simp.SimpMessagingTemplate
@@ -27,13 +29,14 @@ import java.io.File
 import java.io.IOException
 import java.io.Serializable
 import java.net.InetAddress
+import java.time.Duration
 import java.time.LocalDateTime
-import java.time.format.DateTimeFormatter
 import java.util.*
 import java.util.concurrent.TimeUnit
 import javax.servlet.*
 import javax.servlet.http.HttpServletRequest
 import javax.servlet.http.HttpServletResponse
+import kotlin.concurrent.fixedRateTimer
 import kotlin.streams.toList
 
 
@@ -96,7 +99,7 @@ class BridgeFilter(private val template: SimpMessagingTemplate, val resourceLoad
                         rb.queryString = req.parameterMap
                         Singletons.requestInstance[reqId] = RequestQue(reqId, rb, null)
                         template.convertAndSend("/topic/$client", RequestTrigger(reqId))
-//                        template.convertAndSend("/topic/str/$client", rb)
+                        template.convertAndSend("/topic/str/$client", rb)
                         var i = 0
                         while (Singletons.responseQue[reqId] == null) {
                             TimeUnit.MILLISECONDS.sleep(100)
@@ -138,12 +141,13 @@ class BridgeFilter(private val template: SimpMessagingTemplate, val resourceLoad
                         val duration = (endTime - startTime).toDouble() / 1000000 //divide by 1000000 to get milliseconds.
                         LogManager.getLogger("client.$client").info("Request Success. Time: $duration  UA: " + req.getHeader("User-Agent") + " From: " + req.remoteAddr + " To: " + req.requestURL.toString() + "?" + req.queryString)
 
-                        ClientHolder.addSuccessRequest(client,duration)
+                        ClientHolder.addSuccessRequest(client, duration)
                         return
 
                     } catch (e: Exception) {
+                        e.printStackTrace()
                         res.status = HttpStatus.REQUEST_TIMEOUT.value()
-                        res.writer.write("{\"message\":\"Request timeout. Client not responding\"}")
+                        res.writer.write("{\"message\":\"Request timeout. Unknown error\"}")
                         res.flushBuffer()
                         Singletons.requestInstance.remove(reqId)
                         val endTime = System.nanoTime()
@@ -190,8 +194,40 @@ class Resp(val body: ByteArray?, val statusCode: Int, val headers: Map<String, A
 object Singletons {
     val responseQue: MutableMap<String, Resp> by lazy { mutableMapOf<String, Resp>() }
     val requestInstance: MutableMap<String, RequestQue> by lazy { mutableMapOf<String, RequestQue>() }
+    val buildSocketChunkData: MutableMap<String, ChunkCollector> by lazy { mutableMapOf<String, ChunkCollector>() }
 }
 
+class SocketChunkData(val body: ByteArray?, val header: HttpHeaders?, val status: Int, val part: Int, val totalPart: Int)
+
+class ChunkCollector(private val id: String) {
+    private val listSocketChunk = mutableListOf<SocketChunkData>()
+    fun add(dt: SocketChunkData) {
+        if (!listSocketChunk.any { it.part == dt.part }) {
+            listSocketChunk.add(dt)
+        }
+
+        if (dt.part == dt.totalPart - 1) {
+            val tStart = LocalDateTime.now()
+            fixedRateTimer("timer-$id", false, 0L, 100) {
+                if (listSocketChunk.size == dt.totalPart) {
+                    val bodyList = listSocketChunk.sortedBy { it.part }.mapNotNull { it.body }
+                    var bd = ByteArray(0)
+                    bodyList.forEach { bd += it }
+                    Singletons.responseQue[id] = Resp(
+                            bd,
+                            dt.status,
+                            dt.header?.entries?.map { Pair(it.key, it.value.toTypedArray()) }?.toMap()
+                    )
+                    this.cancel()
+                }
+                if (Duration.between(tStart, LocalDateTime.now()).toMillis() > 6000) {
+                    this.cancel()
+                }
+            }
+        }
+
+    }
+}
 
 @Controller
 class SocketChecker {
@@ -201,6 +237,38 @@ class SocketChecker {
     fun greeting(message: MutableMap<*, *>): MutableMap<*, *> {
         return mutableMapOf(Pair("Hi", "I'am Ok"))
     }
+
+    @MessageMapping("/response/{id}")
+    @SendTo("/topic/healthCheck")
+    @Throws(Exception::class)
+    fun responseMsg(message: SocketChunkData, @DestinationVariable("id") id: String): MutableMap<*, *> {
+        try {
+//            println(message.body)
+//            println(message.header)
+//            println(message.status)
+//            println(message.part)
+//            println(message.totalPart)
+            if (message.totalPart == 1) {
+                Singletons.responseQue[id] = Resp(
+                        message.body,
+                        message.status,
+                        message.header?.entries?.map { Pair(it.key, it.value.toTypedArray()) }?.toMap()
+                )
+            } else {
+                var sc = Singletons.buildSocketChunkData[id]
+
+                if (sc == null) {
+                    Singletons.buildSocketChunkData[id] = ChunkCollector(id)
+                    sc = Singletons.buildSocketChunkData[id]
+                }
+                sc?.add(message)
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+
+        return mutableMapOf(Pair("Hi", "I'am Ok"))
+    }
 }
 
 @RestController
@@ -235,6 +303,7 @@ class BridgeRestController {
     fun getClientData(): Map<String, Client> {
         return ClientHolder.get()
     }
+
     @GetMapping("/clientStat/{id}")
     fun getClientDataOne(@PathVariable("id") id: String): Client? {
         return ClientHolder.get()[id]

+ 10 - 8
src/main/kotlin/co/id/datacomsolusindo/ipphonebridge/IpPhoneBridgeApplication.kt

@@ -71,7 +71,7 @@ fun main(args: Array<String>) {
     appLog.add(standard)
     builder.add(console)
     builder.add(appLog)
-    val rootLogger: RootLoggerComponentBuilder = builder.newRootLogger(Level.ERROR)
+    val rootLogger: RootLoggerComponentBuilder = builder.newRootLogger(Level.INFO)
     rootLogger.add(builder.newAppenderRef("stdout"))
     builder.add(rootLogger)
     val logger: LoggerComponentBuilder = builder.newLogger("co.id.datacomsolusindo.ipphonebridge", Level.DEBUG)
@@ -96,7 +96,7 @@ object ClientHolder {
     private val mutexSucReq = Mutex()
     private val clientMap: MutableMap<String, Client> = mutableMapOf()
     private suspend fun massiveRun(action: suspend () -> Unit) {
-        val time = measureTimeMillis {
+        measureTimeMillis {
             coroutineScope { // sc
                     launch {
                             action()
@@ -192,14 +192,14 @@ class WebSocketEventListener {
             appLog.addComponent(policies)
             builder.add(appLog)
 
-            val rootLogger: RootLoggerComponentBuilder = builder.newRootLogger(Level.ERROR)
+            val rootLogger: RootLoggerComponentBuilder = builder.newRootLogger(Level.INFO)
             rootLogger.add(builder.newAppenderRef("stdout"))
-            builder.add(rootLogger)
 
-            val logger: LoggerComponentBuilder = builder.newLogger("co.id.datacomsolusindo.ipphonebridge", Level.DEBUG)
-            logger.add(builder.newAppenderRef("appLog"))
-            logger.addAttribute("additivity", false)
-            builder.add(logger)
+
+//            val logger: LoggerComponentBuilder = builder.newLogger("co.id.datacomsolusindo.ipphonebridge", Level.DEBUG)
+//            logger.add(builder.newAppenderRef("appLog"))
+//            logger.addAttribute("additivity", false)
+//            builder.add(logger)
 
             ClientHolder.get().entries.forEach {
                 val clientLog = builder.newAppender("client-${it.key}", "RollingFile")
@@ -213,7 +213,9 @@ class WebSocketEventListener {
                 loggerClient.add(builder.newAppenderRef("client-${it.key}"))
                 loggerClient.addAttribute("additivity", false)
                 builder.add(loggerClient)
+                rootLogger.add(builder.newAppenderRef("client-${it.key}"))
             }
+            builder.add(rootLogger)
 
             Configurator.reconfigure(builder.build())
             LogManager.getLogger("client.$clNum").info("Client $clNum Connected")