最后更新于 .

游戲內小紅點算是一個極其常用的功能了,之前在德州里面也有過實現。
然而之前的實現實在是亂七八糟,所以這次也是將其做了徹底的重寫,并把方案跟大家分享一下。

我們將游戲內小紅點可以分為三類:

  1. 服務器小紅點-服務器自動清除

    比如,我們常見的每日任務,成長任務,活動等。
    以每日任務舉例:
    當有任務獎勵可以領取時,在每日任務按鈕上就顯示小紅點。
    當任務獎勵全部領取完畢后,小紅點消失。

  2. 服務器小紅點-客戶端告知服務器清除

    比如,信箱功能,新好友通知,好友申請通知。
    以信箱舉例:
    有新郵件,則信箱按鈕就顯示小紅點。
    打開信箱后,如果信箱內分標簽頁,則判斷標簽頁下的郵件列表,如果有新郵件,則在標簽上顯示小紅點。
    當標簽頁打開之后,標簽頁上小紅點消失。 當所有標簽頁的小紅點都消失后,信箱按鈕上的小紅點消失

  3. 客戶端小紅點-客戶端自己維護

    比如聊天功能。

    登錄時,拉取所有未讀消息,如果有消息的話,大廳聊天按鈕需要顯示小紅點。
    之后,當收到新的好友消息的時候,大廳聊天按鈕需要顯示小紅點。
    當點擊聊天按鈕進入具體的聊天頁面時,每個有新消息的好友頁簽,需要顯示小紅點。
    當點擊該頁簽時,小紅點消失。
    當所有頁簽的小紅點消失后,大廳聊天按鈕的小紅點消失。

接下里我們說一下具體的實現。

首先,所有服務器小紅點的狀態,在用戶登錄的時候,就應該返回。
所以我們在登錄協議里面增加了一個red_points字段.

repeated int32 red_points = 1;

我們為每種小紅點定義了一種類型,在red_points中即代表有小紅點,否則代表沒有。

而當進入游戲后,小紅點的狀態是可能動態變化的。所以我們需要定義一個主動下發的協議,通知小紅點狀態變化。

message EvtRedPointsChanged {
    map<int32, bool> map_red_points = 1;
}

最后,服務器端需要提供一個接口,供客戶端主動清除小紅點

message ReqClearRedPoints {
    repeated int32 red_points = 1;
}

這樣,我們的基礎準備工作就結束了。

接下來,就是具體的實現方法了。

  1. 服務器小紅點-服務器自動清除

    服務器端再當狀態發生改變時,就發出對應的信號,在信號處理函數中,計算新的red_points,之后下發EvtRedPointsChanged。
    這樣,無論小紅點是增加還是刪除,都會通過EvtRedPointsChanged下發給客戶端。

  2. 服務器小紅點-客戶端告知服務器清除

    以信箱為例。

    用戶登陸后,假設信箱有小紅點標識,于是用戶打開信箱。
    此時,客戶端向服務器請求信件列表,并緩存在本地,并與老的郵件列表做對比,檢查每個標簽頁下是否有新增郵件。
    有新增郵件的標簽頁,需要顯示小紅點。
    當用戶點擊某個標簽頁時,將該標簽頁的小紅點標記消失。
    如果所有標簽頁都沒有小紅點時,則信箱的整體小紅點消失,并向服務器發送ReqClearRedPoints來清空小紅點。

  3. 客戶端小紅點-客戶端自己維護

    以聊天舉例。

    首先所有的聊天消息都應該有一個絕對唯一的msg_id,并且服務器只會通知一次聊天消息,之后就會從服務器刪除。
    包括登錄后拉取的離線時收到的聊天消息也是如此,服務器返回之后,在服務器端就不再保存了。

    客戶端收到消息后需要分room緩存在本地,這里的room是一個概念,比如群聊天就是群ID,和好友聊天就是好友的uid。
    并將收到新消息的room標記上小紅點。
    之后點擊進入該room時,就清除掉小紅點。
    當所有room的小紅點都清除掉之后,就清除掉大廳聊天按鈕的小紅點。

理論基本就是這樣了。

具體實現的話,建議多使用redis,利用好redis的數據結構和自動過期特性,性能和可維護性都會高不少。

Pingbacks

Pingbacks已打開。

Trackbacks

引用地址

評論

  1. adrain

    adrain on #

    服務器不存儲用戶已讀信件,僅靠客戶端自己的緩存。
    在還有未讀的情況下,即還沒有請求服務器ReqClearRedPoints。
    客戶端清掉緩存,或者卸載重新安裝,
    重新登錄,
    整體小紅點還會有,標簽頁的小紅點是哪個標簽頁的呢?

    Reply

    1. Dante

      Dante on #

      其實清緩存或者重裝的概率還是比較低的,我的建議是所有頁簽都標記小紅點,一般頁簽數也不會太多,用戶都點一遍就可以了。

      Reply

發表評論