前面幾篇基本已經實現了大部分即時通訊功能:聊天,群聊,傳送檔案,圖片,訊息。不過這些業務都是比較粗獷的。下面我們就把業務細化,之前用的是死資料,那我們就從加好友開始吧。加好友,首先你得知道你要加誰。Layim介面右下角有個+號,點選它之後就會彈出查詢好友的介面,不過那個介面需要自定義。由於前端不是我的強項,勉強湊了個頁面。不過不要在意這些細節。這些都不重要,今天主要介紹一下ElasticSearch搜尋解決方案。它是一個基於Lucene的搜尋伺服器。它提供了一個分散式多使用者能力的全文搜尋引擎,基於RESTful web介面。不熟悉Elastic的也不要緊,本篇的搜尋查詢好友用關聯式資料庫一樣實現。(不想對ES做深入研究的可以簡單看一下思路即可)
首先安裝好ES環境。安裝步驟可以參考 http://www.cnblogs.com/panzi/p/5659697.html。
OK,先看一下成型效果圖,第一張是使用者,第二個是群。
好的,介面就是這樣。當然要繫結什麼資料可以自己定義,比如繫結簽名,男女或者其他資訊等,都可以,在高階一點,把是否線上資訊加上。既然用了layui,那順帶著繫結外掛我就直接用laytpl了。前端模板如下:(一個使用者模板,一個群模板)。
再說資料來源,既然我用到了ElasticSearch(下文用ES代替),但是資料庫(MSSQL)也儲存了相應的資訊。這就需要,當一個使用者註冊進來之後,我們還需要將該搜尋資訊儲存到ES中。虛擬碼如下:
var dt = UserRegister(); if(dt){
//如果使用者註冊成功,返回了相應的資訊,我們就把他在加到ES中去。 AdduserInfoToElastic(dt); }
下圖就是ES中儲存的使用者資訊,這些使用者資訊是和資料庫中的資料同步的,因此,修改使用者資訊的時候,此表中的資料也要同步。當然有延遲也沒問題。
用ES的一個好處呢就是快,他能幫你做快取,幫你分詞查詢。我們做練習用資料庫搜尋幾十條沒問題。如果資料量大了,搜尋條件複雜了,ES就能體現出他的優勢了。現在我用的搜尋條件很簡單,一個是IM號,類似QQ,一個就是暱稱。對接ES的客戶端是PlainElastic.Net,用nuget安裝即可。 install-package PlainElastic.Net.
ES有自己的查詢語法,又複雜的也有簡單點的,我就用一些簡單的,畢竟我也沒太深入研究。正如前文所說,它提供了Restful api。我們查詢的路徑就是:127.0.0.1:9200/layim/layim_user/_search POST方法,POST的引數如下:
{ "query": { "match_all": {}//沒有條件的時候就是match_all相當於查詢所有 }, "from": 0,//分頁開始 "size": 50,//每頁條數 "sort": { //排序,根據 province 正序排序 "province": { "order": "asc" } } }
上邊的是查詢所有的情況,當使用者輸入了查詢條件時候,比如精確查詢IM號為 288186 的使用者,搜尋條件如下:
{ "query": { "filtered": { "filter": { "or": [ //or 查詢,下面的條件符合一個即可 { "term": { "im": 288186 //im =288186 } }, { "query": { "match_phrase": { //短語查詢 "nickname": { "query": "288186", //或者暱稱中有288186 "slop": 0 } } } } ] } } }, "from": 0, "size": 50 }
不熟悉語法的同學可能看不太懂,總之上邊這些引數的意思就是 select top 50 * from layim_user where im=288186 or nickname like '%288186%'
查詢結果他會把查詢到的總數和耗時(ms)返回,像幾萬條資料的話大部分就是幾十毫秒甚至不到十毫秒。相對於從資料用查,速度還是可以的。
基於PlainElastic.NET我又封裝了一層查詢的核心方法:
public BaseQueryEntity<T> QueryBayConditions(string query) { try { string cmd = CreateSearchCommand();//構造查詢命令 OperationResult result = Client.Post(cmd, query);//Post query引數查詢 var data = serializer.ToSearchResult<T>(result.Result); //返回結果轉換 return GetResults(data); } catch (Exception ex) { ESLog.WriteLogException(MethodBase.GetCurrentMethod(), "查詢條件:" + query); ESLog.WriteLogException(MethodBase.GetCurrentMethod(), ex); return new BaseQueryEntity<T>(); } }
public class BaseQueryEntity<T> where T :BaseEntity { /// <summary> /// 命中條數 /// </summary> public long hits { get; set; } /// <summary> /// 花費時間(單位ms) /// </summary> public long took { get; set; } public IEnumerable<T> list { get; set; } }
查詢結果json:
總共有3883個使用者,ES查詢用了5ms,加上http請求耗時,總共耗時為45毫秒。
寫到這裡呢,就暫時對ES做個簡單的總結,其實如果做練習的話也沒必要用他來查,直接查資料庫就可以了,如果再配合快取的話速度也不慢,而且今天講的業務邏輯也不復雜。說白了,本篇就講了個CRUD的 Retrieve。(R)還有聊天記錄順便說一下,也是用ES查的,不過到時候會增加一些小的效果。我也不賣關子了,就是模糊查詢的關鍵字高亮效果。
下面繼續說加好友流程,首先,如果你想吧一個使用者加為好友首先,得傳送加好友請求吧,類似QQ。當然,如果那個人設定了任何人都可以加好友,是不是就可以直接加上了。如果那個人設定了不允許任何人加好友,那麼你也沒法加他的,所以,簡單的一個加好友也可以設計的很複雜。本篇就介紹普通的申請流程。點選加好友之後,彈出框,填寫附加訊息:(我們搜尋出288186的使用者新增)
當我們點選傳送之後要考慮什麼呢?先不要看下文,仔細思考一下。5 ,4, 3 ,2, 1。。。
沒錯,就是如果對方恰好線上的處理,和對方不線上的處理、如果對方線上,儲存到資料庫並且即時提醒。不線上,儲存到資料庫,等下次登入提醒使用者。詳細做法下一篇再寫吧。先貼一個預告圖:
本篇貼的圖比較多,講了一些業務上的東西和ES的簡單使用,場景和使用方式等。本篇就到這裡吧。
下篇預告:【中級】ASP.NET SignalR 與 LayIM2.0 配合輕鬆實現Web聊天室(五) 之 加好友,加群訊息提示,Hub中的User用法。
想要學習的小夥伴,可以關注我的部落格哦,我的QQ:645857874,Email:fanpan26@126.com