過濾服務器的重複消息

需求場景描述:
C/S結構的程序. 客戶端監聽服務器端發來的信息,並向用戶報告. 內容相同的信息,服務器端可能會重複發送3到5次, 每次間隔0.01秒. 用戶希望, 對於這些重複發送的信息, 只報告一次即可.
 
分析:
這裏面有幾個關鍵的問題:
首先, 如何判斷當前的消息是否是重複消息. 可以通過保存一個消息列表來實現.
這裏有兩種實現方法: 1, 保證消息列表是絕對最新的, 這樣,新消息到來的時候只要判斷列表中是否存在即可. 2, 不保證列表是絕對最新, 新消息來的時候除了判斷內容,還要判斷時間. 這兩種方案其實是在“實時維護列表的嚴格最新”和“搜索時的進行比較的條件和次數”兩件事情之間的權衡.
 
由此引發第二個問題:列表更新的時機。列表有必要在任何時刻都是嚴格最新的嗎?顯然沒有。即使需要最新,也只要在搜索列表之前保證是最新的就可以了。所以,無論是掃描線程,還是計時器,雖然嚴格符合了程序的要求,但是不必要的。因此,我們可以給出幾個更新的時機,比如,每隔固定時間進行更新,有消息到達時進行更新,或消息數量到達某一上限時進行更新,在其中權衡。(酷似內存管理中的“快表淘汰算法”)
 
權衡下來,對於第一個問題,對列表的遍歷和維護的開銷要大於增加一個比較條件的開銷。對於第二個問題,我們選擇了在消息數量達到某個閾值時進行更新。如下4個方案,展示了對以上兩個關鍵問題逐步改善的過程。
 
方案1:
把收到的信息保存起來, 每當新來一個信息, 和保存的消息比較, 如果消息列表中存在某個消息和當前消息內容相等(無需比較時間. 因爲列表中的消息一定是最新的), 則丟棄該消息. 否則,向用戶報告該消息, 並加入消息列表. 消息列表中的每條消息都附加一個計時器. 到0.05秒後自行離開消息列表.
 
方案2:
篩選消息的方法和方案1相同. 和方案1的差別是, 無需給每個消息都附加計時器. 而是另外啓動一個監視線程, 每隔0.01秒掃描消息列表, 刪除時間戳和當前時間之差超過0.05秒的消息.
 
方案3:
把收到的信息保存起來, 每當新來一個信息, 首先掃描消息列表, 刪除時間戳和當前時間之差超過0.05秒的消息. 然後查找消息列表, 如果消息列表中存在某個消息和當前消息內容相等, (無需檢查時間戳. 因爲列表中的過期的消息已經被刪除), 則丟棄該消息. 否則,向用戶報告該消息, 並加入消息列表.
 
方案4:
每當新來一個信息, 查找消息列表. 如果消息列表中存在某個消息和當前消息內容相等, 並且時間戳之差小於0.05(因爲列表中的消息不一定是最新的), 則丟棄該消息. 否則,向用戶報告該消息, 並加入消息列表. 另外, 不使用監視線程來掃描消息列表. 而是規定一個閾值, 每當消息列表中的消息數量超過這個閾值的時候, 掃描消息列表, 刪除時間戳和當前時間之差超過0.05秒的消息.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章