Files
AAS_NewGeneration/src/barix/TCP_Barix_Command_Server.kt
rdkartono 2ad26c3ef6 commit 08/10/2025
BarixConnection Activate Deactivate Relays
2025-10-08 16:33:19 +07:00

116 lines
4.5 KiB
Kotlin

package barix
import codes.Somecodes.Companion.ValidString
import kotlinx.coroutines.*
import org.tinylog.Logger
import java.net.ServerSocket
import java.net.Socket
import java.util.function.Consumer
@Suppress("unused")
class TCP_Barix_Command_Server {
lateinit var tcpserver: ServerSocket
lateinit var job: Job
private val socketMap = mutableMapOf<String, Socket>()
private val regex = """STATUSBARIX;(\d+);(\d+);?(\d)?"""
private val pattern = Regex(regex)
/**
* Start TCP Command Server
* @param port The port number to listen on (default is 5001)
* @param cb A callback function that will be called when a valid command is received
* @return true if successful
*/
fun StartTcpServer(port: Int = 5001, cb: Consumer<BarixStatus>): Boolean {
try {
val tcp = ServerSocket(port)
tcpserver = tcp
job = CoroutineScope(Dispatchers.IO).launch {
Logger.info { "TCP StreamerOutput server started on port $port" }
while (isActive) {
if (tcpserver.isClosed) break
try {
val socket = tcpserver.accept()
CoroutineScope(Dispatchers.IO).launch {
val key : String = socket.inetAddress.hostAddress
socketMap[key] = socket
Logger.info { "Start communicating with Streamer Output with IP : $key" }
val din = socket.getInputStream()
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)
if (ValidString(str)) {
// Valid command from Barix is in format $"STATUSBARIX;VU;BuffRemain;StatusData"$
pattern.find(str)?.let { matchResult ->
val (vu, buffremain, statusdata) = matchResult.destructured
val status = BarixStatus(
socket.inetAddress.hostAddress,
vu.toInt(),
buffremain.toInt(),
statusdata.toIntOrNull() ?: 0
)
//Logger.info { "Received valid command from $key : $status" }
cb.accept(status)
} ?: run {
Logger.warn { "Invalid command format from $key : $str" }
}
}
}
}
Logger.info { "Finished communicating with Streamer Output with IP $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}" }
}
return false
}
/**
* Get Socket by IP address
* @param ip The IP address of the client
* @return Socket if found, null otherwise
*/
fun getSocket(ip: String): Socket? {
return socketMap[ip]
}
}