com.simiacryptus.skyenet.webui.chat.ChatServer.kt Maven / Gradle / Ivy
package com.simiacryptus.skyenet.webui.chat
import com.simiacryptus.skyenet.core.platform.ApplicationServices.authenticationManager
import com.simiacryptus.skyenet.core.platform.AuthenticationInterface
import com.simiacryptus.skyenet.core.platform.Session
import com.simiacryptus.skyenet.core.platform.StorageInterface
import com.simiacryptus.skyenet.core.platform.User
import com.simiacryptus.skyenet.webui.servlet.NewSessionServlet
import com.simiacryptus.skyenet.webui.session.SocketManager
import org.eclipse.jetty.servlet.DefaultServlet
import org.eclipse.jetty.servlet.ServletHolder
import org.eclipse.jetty.util.resource.Resource
import org.eclipse.jetty.webapp.WebAppContext
import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest
import org.eclipse.jetty.websocket.server.JettyWebSocketServlet
import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory
import java.time.Duration
abstract class ChatServer(private val resourceBase: String) {
abstract val applicationName: String
open val dataStorage: StorageInterface? = null
val sessions: MutableMap = mutableMapOf()
inner class WebSocketHandler : JettyWebSocketServlet() {
override fun configure(factory: JettyWebSocketServletFactory) {
with(factory) {
isAutoFragment = false
idleTimeout = Duration.ofMinutes(10)
outputBufferSize = 1024 * 1024
inputBufferSize = 1024 * 1024
maxBinaryMessageSize = 1024 * 1024
maxFrameSize = 1024 * 1024
maxTextMessageSize = 1024 * 1024
this.availableExtensionNames.remove("permessage-deflate")
}
factory.setCreator { req, resp ->
try {
if (req.parameterMap.containsKey("sessionId")) {
val session = Session(req.parameterMap["sessionId"]?.first()!!)
ChatSocket(
if (sessions.containsKey(session)) {
sessions[session]!!
} else {
val user =
authenticationManager.getUser(req.getCookie(AuthenticationInterface.AUTH_COOKIE))
val sessionState = newSession(user, session)
sessions[session] = sessionState
sessionState
}
)
} else {
throw IllegalArgumentException("sessionId is required")
}
} catch (e: Exception) {
log.debug("Error configuring websocket", e)
resp.sendError(500, e.message)
null
}
}
}
}
abstract fun newSession(user: User?, session: Session): SocketManager
open val baseResource: Resource? get() = Resource.newResource(javaClass.classLoader.getResource(resourceBase))
private val newSessionServlet by lazy { NewSessionServlet() }
private val webSocketHandler by lazy { WebSocketHandler() }
private val defaultServlet by lazy { DefaultServlet() }
open fun configure(webAppContext: WebAppContext) {
webAppContext.addServlet(ServletHolder(javaClass.simpleName + "/default", defaultServlet), "/")
webAppContext.addServlet(ServletHolder(javaClass.simpleName + "/ws", webSocketHandler), "/ws")
webAppContext.addServlet(ServletHolder(javaClass.simpleName + "/newSession", newSessionServlet), "/newSession")
}
companion object {
private val log = org.slf4j.LoggerFactory.getLogger(ChatServer::class.java)
fun JettyServerUpgradeRequest.getCookie(name: String) = cookies?.find { it.name == name }?.value
}
}