需求場景描述:
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秒的訊息.
伺服器訊息推送
客戶端定時向伺服器傳送ajax請求,伺服器接到請求後馬上返回響應資訊並關閉連線 優點 後端程式編寫比較容易 缺點 求中有大半是無用,浪費頻寬和伺服器資源 客戶端向伺服器傳送ajax請求,伺服器接到請求後hold住連線,直到有新訊息才返回響應資訊並關閉連線,客戶端處理完響應資訊後再向伺服器傳送新的請求...
訊息佇列伺服器 memcacheq的搭建
安裝步驟 tar zxvflibevent 1.4.14b stable.tar.gz cd libevent 1.4.14b stable configure make make install ln s usr local lib libevent 1.4.so.2 usr lib libeve...
訊息發布 訂閱伺服器 Laharsub
laharsub是一種構建在三層架構之上的發布 訂閱訊息伺服器 前端 客戶端,中間層 web服務,後端 帶有發布 訂閱功能和儲存能力的系統。客戶端一般是瀏覽器,但是可以是所有已知能夠做出http請求的程式。中間層是一種wcf的http服務,它會從客戶端接收訊息,並向其傳送訊息,而後端會包含真正的與訊...