package commandServer import codes.Somecodes.Companion.ValidString import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.tinylog.Logger import java.net.ServerSocket import java.net.Socket import java.util.function.Consumer @Suppress("unused") class TCP_Android_Command_Server { private var tcpserver: ServerSocket? = null private var job: Job? = null private val socketMap = mutableMapOf() /** * Start TCP Command Server * @param port The port to listen on, default is 5003 * @param cb The callback function to handle incoming messages * @return true if successful */ fun StartTcpServer(port: Int = 5003, cb: Consumer): Boolean { try { val tcp = ServerSocket(port) tcpserver = tcp job = CoroutineScope(Dispatchers.IO).launch { Logger.info { "TCP server started" } while (isActive) { if (tcpserver?.isClosed == true) break try { tcpserver?.accept().use { socket -> { CoroutineScope(Dispatchers.Main).launch { if (socket != null) { val key : String = socket.inetAddress.hostAddress+":"+socket.port socketMap[key] = socket Logger.info { "Start communicating with $key" } socket.getInputStream().use { din -> { while (isActive) { if (din.available()>0){ val bb = ByteArray(din.available()) din.read(bb) // B4A format, 4 bytes di depan adalah size val str = String(bb,4,bb.size-4) str.split("@").forEach { if (ValidString(it)){ cb.accept(it) } } } } } } Logger.info { "Finished communicating with $key" } socketMap.remove(key) } } } } } catch (ex: Exception) { Logger.error { "Failed accepting TCP Socket, Message : ${ex.message}" } } } Logger.info { "TCP server stopped" } } return true } catch (e: Exception) { Logger.error { "Failed to StartTcpServer, Message : ${e.message}" } } return false } /** * Stop TCP Command Server * @return true if succesful */ fun StopTcpCommand(): Boolean { try { tcpserver?.close() runBlocking { socketMap.values.forEach { it.close() } socketMap.clear() job?.join() } Logger.info { "StopTcpCommand success" } return true } catch (e: Exception) { Logger.error { "Failed to StopTcpServer, Message : ${e.message}" } } finally { tcpserver = null } return false } }