一步一步打造WebIM 2 訊息快取

2021-06-03 00:07:17 字數 2894 閱讀 2901

**:,盧春城專欄

在 一步一步打造webim(1) 一文中,已經介紹了如何實現乙個簡單的webim,但是,這個webim有乙個問題,就是每一次新增訊息***時,都必須訪問一次資料庫去查詢是否有訊息,顯然,如果使用者比較多時,必然對資料庫的壓力比較大。解決這個問題的乙個方法就是先將訊息快取在記憶體中,不立即寫入資料庫,等到快取滿了才寫入資料庫。本文將介紹如何實現訊息快取。

實現乙個訊息快取管理類,以使用者為單位快取所有訊息,每乙個使用者對應著乙個list,儲存著該使用者新收到的訊息,訊息快取管理用乙個hashtable儲存著所有使用者對應的list。

具體實現**如下:

public class 

messagecachemanagement

}private messagecachemanagement()

int32 m_count = 0;

hashtable m_cache = new

hashtable();

list

getusermessagecache(string user)

return m_cache[user] as

list;}

/// ///

清除快取

///

public void clear()

m_count = 0;}}

/// ///

獲取所有快取的訊息

///

///

public

list

getall()

}return msgs;}}

/// ///

獲取某一使用者快取的訊息的最小時間

///

public

nullable

getmincreatedtime(string user)

}/// ///

在快取中插入一條訊息

///

///

///

public void insert(string user, message msg)

lock (usermsgs)

}/// ///

查詢快取中接受者為user,傳送時間大於from的訊息

///

public

list

find(string user, datetime from)

lock (usermsgs)

return msgs;}}

/// ///

獲取訊息總量

///

public

int32 count

}}

增加訊息快取後,新增訊息***的流程也要修改,具體思路是先獲取訊息接收者在快取中傳送時間最早的訊息的傳送時間,顯然,如果***的from大於或等於這個最小傳送時間時,無需訪問資料庫,可以直接訪問快取。具體**修改為:

/// /// 

新增訊息***,如果查詢到符合***條件的訊息,返回false,此時不會新增***

///

如果沒有查詢到符合***條件的訊息,返回true,此時***將被新增到m_listeners中

///

public bool addlistener(string receiver, string sender, nullable

from, webim_asyncresult asynresult)

list

listeners = m_listeners[receiver] as

list

;//獲取使用者receiver快取的訊息的最小傳送時間

nullable

min = messagecachemanagement.instance.getmincreatedtime(receiver);

list

messages = new

list

();//當from >= 快取在記憶體中的訊息的最小時間時,不必查詢資料庫

if (min == null || from == null || from.value < min.value)

//在快取中查詢

messages.addrange(messagecachemanagement.instance.find(receiver, from.value));

if (messages.count == 0)

else

return messages.count == 0;

}}

增加訊息快取後,傳送訊息的流程也要修改,具體思路是:先將訊息儲存到快取中,之後判斷快取的訊息的總數,如果超過設定的上限,就將訊息寫入資料庫。具體**修改為(您可以通過修改max_cache_count修改快取訊息數的上限):

/// /// 

插入新的訊息,插入訊息後將查詢m_listeners中是否有符合條件的***,如存在,同時將訊息傳送出去

///

public

message newmessage(string receiver, string sender, datetime createdtime, string content)

}foreach (messagelistener listener in removelisteners)

}messagecachemanagement.instance.insert(receiver, message);

if (messagecachemanagement.instance.count >= max_cache_count)

trans.commit();

}catch

messagecachemanagement.instance.clear();

}return message;

}}

一步一步打造WebIM 2 訊息快取

webim系列文章 在一步一步打造webim 1 一文中,已經介紹了如何實現乙個簡單的webim,但是,這個webim有乙個問題,就是每一次新增訊息 時,都必須訪問一次資料庫去查詢是否有訊息,顯然,如果使用者比較多時,必然對資料庫的壓力比較大。解決這個問題的乙個方法就是先將訊息快取在記憶體中,不立即...

一步一步打造WebIM 1

webim系列文章 1.comet 在.net要實現comet就要用到ihttpasynchandler,在開始閱讀文章前,建議先了解一下ihttpasynchandler。2.lesktop lesktop是一款用於開發ria 的開源js介面庫,lesktop提供了乙個功能強大的視覺化開發工具幫助...

一步一步打造WebIM 3 效能測試

webim系列文章 在一步一步打造webim 1 和 2 中,已經討論了如何開發乙個webim,並且使用快取來提高webim的效能,本文將編寫乙個程式模擬大量使用者登入來對webim進行效能測試。測試一將模擬200個使用者同時登入的聊天室,每個使用者以1條訊息 秒的速度傳送訊息 由於網路和伺服器處理...