Add polling
This commit is contained in:
parent
927649bba6
commit
ce4e4635e3
|
@ -18,7 +18,15 @@ data class Message(
|
|||
val type: MessageType,
|
||||
val repository: RepositoryType,
|
||||
val id: Long
|
||||
)
|
||||
) {
|
||||
companion object {
|
||||
val empty = Message(
|
||||
MessageType.UPDATE,
|
||||
RepositoryType.ANNOUNCEMENT,
|
||||
0L
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
enum class MessageType {
|
||||
CREATE, UPDATE, DELETE
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.w3c.xhr.XMLHttpRequest
|
|||
import kotlin.browser.document
|
||||
import kotlin.browser.window
|
||||
|
||||
class WebSocketClient {
|
||||
class PushServiceClient {
|
||||
private val prefix = js("prefix")
|
||||
private val url = "$prefix/api/updates"
|
||||
private val body = document.body ?: createHtmlView()
|
|
@ -12,7 +12,7 @@ import de.westermann.kwebview.components.init
|
|||
import kotlin.browser.document
|
||||
|
||||
fun main() = init {
|
||||
WebSocketClient()
|
||||
PushServiceClient()
|
||||
|
||||
if (document.getElementsByClassName("calendar").length > 0) {
|
||||
initCalendar()
|
||||
|
|
|
@ -21,15 +21,15 @@ object AnnouncementRepository {
|
|||
|
||||
suspend fun getAnnouncement(): String {
|
||||
val json = repositoryGet("$prefix/api/announcement") ?: return ""
|
||||
return parser.parse(json, String.serializer())
|
||||
return json as String
|
||||
}
|
||||
|
||||
suspend fun setAnnouncement(value: String){
|
||||
return repositoryPost("$prefix/api/announcement", Serialization.stringify(String.serializer(), value))
|
||||
return repositoryPost("$prefix/api/announcement", value)
|
||||
?: throw IllegalStateException("Cannot set announcement!")
|
||||
}
|
||||
|
||||
val handler = object : MessageHandler(RepositoryType.ROOM) {
|
||||
val handler = object : MessageHandler(RepositoryType.ANNOUNCEMENT) {
|
||||
|
||||
override fun onCreate(id: Long) {}
|
||||
|
||||
|
|
|
@ -18,4 +18,4 @@ fun initAnnouncement() {
|
|||
span.textContent = text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,9 @@ import io.ktor.routing.get
|
|||
|
||||
object PushService {
|
||||
|
||||
var leastValidTimestamp = System.currentTimeMillis()
|
||||
private var leastValidTimestamp = System.currentTimeMillis()
|
||||
|
||||
private val messages: MutableList<Pair<Long, Message>> = mutableListOf()
|
||||
|
||||
/**
|
||||
* Save the message with the current timestamp
|
||||
|
@ -22,6 +24,21 @@ object PushService {
|
|||
fun notify(type: MessageType, repository: RepositoryType, id: Long) {
|
||||
val timestamp = System.currentTimeMillis()
|
||||
val message = Message(type, repository, id)
|
||||
|
||||
synchronized(messages) {
|
||||
messages += Pair(timestamp, message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getIndexOfTimestamp(timestamp: Long): Int {
|
||||
val index = messages.binarySearch(Pair(timestamp, Message.empty), compareBy { it.first })
|
||||
val i = if (index < 0) {
|
||||
-index - 1
|
||||
} else {
|
||||
index
|
||||
}
|
||||
|
||||
return if (i < 0) 0 else i
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,12 +46,25 @@ object PushService {
|
|||
* The return Box has the current timestamp. If the leastValidTimestamp is less then the current timestamp set the
|
||||
* valid flag to false and return an empty message list.
|
||||
*/
|
||||
fun getMessages(timestamp: Long?): MessageBox {
|
||||
return MessageBox(
|
||||
System.currentTimeMillis(),
|
||||
timestamp != null && timestamp > leastValidTimestamp,
|
||||
emptyList()
|
||||
)
|
||||
fun getMessages(timestamp: Long): MessageBox {
|
||||
return if (timestamp < leastValidTimestamp) {
|
||||
MessageBox(
|
||||
System.currentTimeMillis(),
|
||||
false,
|
||||
emptyList()
|
||||
)
|
||||
} else {
|
||||
val m = synchronized(messages) {
|
||||
val index = getIndexOfTimestamp(timestamp)
|
||||
messages.drop(index)
|
||||
}
|
||||
|
||||
MessageBox(
|
||||
System.currentTimeMillis(),
|
||||
true,
|
||||
m.map { it.second }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,13 +72,19 @@ object PushService {
|
|||
*/
|
||||
fun gc(timestamp: Long) {
|
||||
leastValidTimestamp = timestamp
|
||||
|
||||
synchronized(messages) {
|
||||
messages.removeIf {
|
||||
it.first < timestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Route.pushService() {
|
||||
get("/api/updates") {
|
||||
try {
|
||||
val timestamp = call.request.queryParameters["timestamp"]?.toLongOrNull()
|
||||
val timestamp = call.request.queryParameters["timestamp"]?.toLongOrNull() ?: 0
|
||||
|
||||
val messageBox = PushService.getMessages(timestamp)
|
||||
|
||||
|
|
Loading…
Reference in a new issue