forked from chookspace/chookchat
		
	Anti timeout ping, user list
This commit is contained in:
		@@ -5,6 +5,8 @@ import io.javalin.websocket.WsContext
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap
 | 
			
		||||
import java.util.UUID
 | 
			
		||||
 | 
			
		||||
import kotlin.concurrent.fixedRateTimer
 | 
			
		||||
 | 
			
		||||
import java.io.File
 | 
			
		||||
import java.io.BufferedReader
 | 
			
		||||
 | 
			
		||||
@@ -17,12 +19,50 @@ fun md5(input:String): String {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object WsSessionManager {
 | 
			
		||||
    var peopleOnline = mutableListOf("")
 | 
			
		||||
    var sessionsList = mutableListOf("")
 | 
			
		||||
 | 
			
		||||
    private val sessions = ConcurrentHashMap<WsContext, String>()
 | 
			
		||||
    private val sessionIds = ConcurrentHashMap<String, WsContext>()
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        fixedRateTimer("websocket-ping", period = 5000) {
 | 
			
		||||
            sendPing()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private fun sendPing() {
 | 
			
		||||
        val deadSessions = mutableListOf<WsContext>()
 | 
			
		||||
 | 
			
		||||
        sessions.keys.forEach { ctx ->
 | 
			
		||||
            try {
 | 
			
		||||
                if (ctx.session.isOpen) {
 | 
			
		||||
                    ctx.send("ping")
 | 
			
		||||
                } else {
 | 
			
		||||
                    deadSessions.add(ctx)
 | 
			
		||||
                }
 | 
			
		||||
            } catch (e: Exception) {
 | 
			
		||||
                println("Error sending ping: ${e.message}")
 | 
			
		||||
                deadSessions.add(ctx)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Clean up any dead sessions
 | 
			
		||||
        deadSessions.forEach { removeSession(it) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun broadcastOnlineUsers() {
 | 
			
		||||
        broadcast("!users:{${peopleOnline.joinToString(",")}}")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun handleUserLogin(username: String) {
 | 
			
		||||
        peopleOnline += username
 | 
			
		||||
        broadcastOnlineUsers()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun addSession(ctx: WsContext) {
 | 
			
		||||
        try {
 | 
			
		||||
            val sessionId = UUID.randomUUID().toString()
 | 
			
		||||
            sessionsList += sessionId
 | 
			
		||||
            sessions[ctx] = sessionId
 | 
			
		||||
            sessionIds[sessionId] = ctx
 | 
			
		||||
        } catch (e: Exception) {
 | 
			
		||||
@@ -34,8 +74,11 @@ object WsSessionManager {
 | 
			
		||||
        try {
 | 
			
		||||
            val sessionId = sessions[ctx]
 | 
			
		||||
            if (sessionId != null) {
 | 
			
		||||
                peopleOnline.removeAt(sessionsList.indexOf(sessionId))
 | 
			
		||||
                sessionsList.removeAt(sessionsList.indexOf(sessionId))
 | 
			
		||||
                sessions.remove(ctx)
 | 
			
		||||
                sessionIds.remove(sessionId)
 | 
			
		||||
                broadcastOnlineUsers()
 | 
			
		||||
            }
 | 
			
		||||
        } catch (e: Exception) {
 | 
			
		||||
            println("Error removing session: ${e.message}")
 | 
			
		||||
@@ -101,6 +144,7 @@ fun handleSentMessage(inputData: String): String {
 | 
			
		||||
    var message = ""
 | 
			
		||||
    var dataType = ""
 | 
			
		||||
    var command = ""
 | 
			
		||||
    var commandArg = ""
 | 
			
		||||
    var isParsingData = 0
 | 
			
		||||
    for (char in inputData) {
 | 
			
		||||
        val character = char
 | 
			
		||||
@@ -119,6 +163,8 @@ fun handleSentMessage(inputData: String): String {
 | 
			
		||||
                    message += character
 | 
			
		||||
                } else if (dataType == "command") {
 | 
			
		||||
                    command += character
 | 
			
		||||
                } else if (dataType == "commandArg") {
 | 
			
		||||
                    commandArg += character
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -177,9 +223,17 @@ fun handleSentMessage(inputData: String): String {
 | 
			
		||||
        chatHistory.appendText("$username: $message ${System.lineSeparator()}")
 | 
			
		||||
        message = ""
 | 
			
		||||
        return("Success")
 | 
			
		||||
    } else if (command != "") {
 | 
			
		||||
        if (command == "sync") {
 | 
			
		||||
            return(chatHistoryView.readText())
 | 
			
		||||
        } else if (command == "login") {
 | 
			
		||||
            WsSessionManager.handleUserLogin(commandArg)
 | 
			
		||||
            return("Login successful")
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        return("No data provided")
 | 
			
		||||
    }
 | 
			
		||||
    return("System: Welcome to Chookpen, $username!")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun syncMessages(inputData: String): String {
 | 
			
		||||
@@ -391,7 +445,8 @@ fun authKey(inputData: String): String {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun main(args: Array<String>) {
 | 
			
		||||
    var users = listOf("")
 | 
			
		||||
    WsSessionManager.peopleOnline.removeAt(0)
 | 
			
		||||
    WsSessionManager.sessionsList.removeAt(0)
 | 
			
		||||
    val app = Javalin.create()
 | 
			
		||||
        .get("/") { ctx -> ctx.result("dingus") }
 | 
			
		||||
        .get("/api/send/{content}") { ctx -> 
 | 
			
		||||
@@ -413,20 +468,25 @@ fun main(args: Array<String>) {
 | 
			
		||||
            ws.onClose { ctx ->
 | 
			
		||||
                WsSessionManager.removeSession(ctx)
 | 
			
		||||
            }
 | 
			
		||||
            ws.onMessage { ctx -> 
 | 
			
		||||
                println(ctx.message()) 
 | 
			
		||||
                val successState = handleSentMessage(ctx.message())
 | 
			
		||||
                if (successState != "Success") {
 | 
			
		||||
                    try {
 | 
			
		||||
                        ctx.send(successState)
 | 
			
		||||
                    } catch (e: Exception) {
 | 
			
		||||
                        println("Error sending error message: ${e.message}")
 | 
			
		||||
            ws.onMessage { ctx ->
 | 
			
		||||
                when (ctx.message()) {
 | 
			
		||||
                    "pong" -> {}
 | 
			
		||||
                else -> {
 | 
			
		||||
                    println(ctx.message()) 
 | 
			
		||||
                    val successState = handleSentMessage(ctx.message())
 | 
			
		||||
                    if (successState != "Success") {
 | 
			
		||||
                        try {
 | 
			
		||||
                            ctx.send(successState)
 | 
			
		||||
                        } catch (e: Exception) {
 | 
			
		||||
                            println("Error sending error message: ${e.message}")
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        val messageContent = extractMessageContent(ctx.message())
 | 
			
		||||
                        WsSessionManager.broadcast(messageContent)
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    val messageContent = extractMessageContent(ctx.message())
 | 
			
		||||
                    WsSessionManager.broadcast(messageContent)
 | 
			
		||||
                }
 | 
			
		||||
            } 
 | 
			
		||||
            }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    .start(7070)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user