iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0

目標

從左畫面將訊息推送到右邊畫面,嗯! 就這樣。
https://ithelp.ithome.com.tw/upload/images/20211009/201386803dh5pbDdXy.png

本示例從主畫面推送訊息,其他開啟本網的使用者無論畫面停留在哪個頁面,皆能接收到該訊息 Notificatin 。

訊息推播

當有資訊要從某頁傳送到另一個畫面,或者從後台將資訊推送給前端畫面時,即可使用Push推送。
Vaadin 使用 Atmosphere framework做為client-server 通訊框架,預設採用 WebSocket 連線,若 Browser或Server不支援的話,則改用 Browser 支援的通訊協定。

一般常見的訊息推播、優惠通知、購買通知、訊息公告皆可用Push/Broadcast。另外,亦可應用在協同編輯、非同步更新、狀態監控...等功能。

BroadCaster

為避免 deadlock 建議使用Queue,透過單獨線程排隊發送,最簡單、安全的方式就是使用 java 的 Synchronized 鎖定。

class Broadcaster {
    companion object{
        var executor: Executor = Executors.newSingleThreadExecutor()
        var listeners = LinkedList<Consumer<String>>()

        @Synchronized
        fun register(listener: Consumer<String>): Registration? {
            listeners.add(listener)
            return Registration {
                synchronized(Broadcaster::class.java) { listeners.remove(listener) }
            }
        }

        @Synchronized
        fun broadcast(message: String) {
            for (listener in listeners) {
                executor.execute { listener.accept(message) }
            }
        }
    }

}

Receiving Broadcasts

在本例中,由於所有的畫面都會設定 layout 為 MainLayout ( @Route("path", layout = MainLayout::class),所以直接將接收寫在此layout上。

    var broadcasterRegistration: Registration? = null
    override fun onAttach(attachEvent: AttachEvent?) {
        val ui = attachEvent!!.ui
        broadcasterRegistration = Broadcaster.register{ newMessage->
            ui.access{
                Notification(newMessage, 3000).open()
            }
        }!!
        super.onAttach(attachEvent)
    }

    override fun onDetach(detachEvent: DetachEvent?) {
        broadcasterRegistration?.let { it.remove() }
        broadcasterRegistration = null
        super.onDetach(detachEvent)
    }

class 上方加上 @Push

@Push
@AllowAll
@Viewport(Viewport.DEVICE_DIMENSIONS)
class MainLayout: KComposite(), RouterLayout, BeforeEnterObserver {
   :
   :
   :
}

Send Message

以下程式碼可寫在任何要發送訊息的頁面上,本例寫在主畫面 MainView.kt

    val txtMessage = textField("message")
    button("Send Broadcast"){
        onLeftClick {
            Broadcaster.broadcast(txtMessage.value)
        }
    }

上一篇
立委名單/提案 Open Data / CsvToBean - day23
下一篇
看焰火囉~ Vaadin 內嵌 iFrame 不跑版自動縮放 - day25
系列文
使用 Kotlin 快速開發 Web 程式 -- Vaadin30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言