广播推送 - day24

目标

从左画面将讯息推送到右边画面,嗯! 就这样。
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)
        }
    }

<<:  [经典回顾]走骇客的路让骇客无路可走?

>>:  JS 24 - 请求支援前,要先发送请求!

Day 21 - Class

Class Es6 的语法糖,简化了上一篇的写法,让程序码更好阅读 这边改写前一篇介绍过的例子 Be...

【Day22】导航元件 - Tabs

元件介绍 Tabs 是一个选项卡切换元件,能够在同一层级的内容组别当中导航、切换。此元件由两个部分构...

Day-13: 目前开发时终端常用的命令指令五虾毁?

在 Rails 的开发过程中,许多指令都是在终端机(Terminal)环境操作。 老实说我现在是菜逼...

IOS、Python自学心得30天 Day-26 Firebase部分

Realtime Database: Storage: Storage rule: rules_ve...

#2 Python教学1

安装 去官网安装就好,按这里。 推荐各位安装python3以上的版本,3版以上现在几乎是主流,许多套...