基于.NetCore開發(fā)博客項目 StarBlog - (11) 實現(xiàn)訪問統(tǒng)計
系列文章
- 基于.NetCore開發(fā)博客項目 StarBlog - (1) 為什么需要自己寫一個博客?
- 基于.NetCore開發(fā)博客項目 StarBlog - (2) 環(huán)境準備和創(chuàng)建項目
- 基于.NetCore開發(fā)博客項目 StarBlog - (3) 模型設(shè)計
- 基于.NetCore開發(fā)博客項目 StarBlog - (4) markdown博客批量導入
- 基于.NetCore開發(fā)博客項目 StarBlog - (5) 開始搭建Web項目
- 基于.NetCore開發(fā)博客項目 StarBlog - (6) 頁面開發(fā)之博客文章列表
- 基于.NetCore開發(fā)博客項目 StarBlog - (7) 頁面開發(fā)之文章詳情頁面
- 基于.NetCore開發(fā)博客項目 StarBlog - (8) 分類層級結(jié)構(gòu)展示
- 基于.NetCore開發(fā)博客項目 StarBlog - (9) 圖片批量導入
- 基于.NetCore開發(fā)博客項目 StarBlog - (10) 圖片瀑布流
- 基于.NetCore開發(fā)博客項目 StarBlog - (11) 實現(xiàn)訪問統(tǒng)計
- 基于.NetCore開發(fā)博客項目 StarBlog - (12) Razor頁面動態(tài)編譯
- 基于.NetCore開發(fā)博客項目 StarBlog - (13) 加入友情鏈接功能
- 基于.NetCore開發(fā)博客項目 StarBlog - (14) 實現(xiàn)主題切換功能
- 基于.NetCore開發(fā)博客項目 StarBlog - (15) 生成隨機尺寸圖片
- 基于.NetCore開發(fā)博客項目 StarBlog - (16) 一些新功能 (監(jiān)控/統(tǒng)計/配置/初始化)
- 基于.NetCore開發(fā)博客項目 StarBlog - (17) 自動下載文章里的外部圖片
- ...
前言
放完端午假期回來,我的博客還沒上線,看著各位大佬的網(wǎng)站都辦得風生水起,我隱約感覺到一絲緊迫感,得抓緊時間寫代碼了~!
前面的文章已經(jīng)把博客網(wǎng)站的基本功能實現(xiàn)起來了,距離網(wǎng)站上線只有一步之遙,然而還有一些細枝末節(jié)之處,對網(wǎng)站的運營或者用戶體驗有很大影響,必須完善的,比如:
- 網(wǎng)站訪問統(tǒng)計
- 圖床
按照先后順序,本文先解決訪問統(tǒng)計的問題。
一提到訪問統(tǒng)計,眾所周知的就是Google Analytics或者百度統(tǒng)計,前者在國內(nèi)無法使用,后者應該是唯一選擇了,但考慮到兩者的功能差距以及該公司的口碑,對我這個小破站來說,我寧愿自己實現(xiàn)一個~
實現(xiàn)
實現(xiàn)起來應該是不難的,為了實現(xiàn)統(tǒng)計、分析,我們需要先記錄,記錄的內(nèi)容包括用戶的IP、設(shè)備、訪問路徑、訪問時間,然后再對這些數(shù)據(jù)進行分析,就可以得出每篇文章、圖片、分類的閱讀量/訪問量。
為了記錄這些數(shù)據(jù),需要在用戶發(fā)起每一個請求時都進行處理,在AspNetCore中有多種實現(xiàn),比如Filter、比如Middleware
這里我選的是中間件的方式
PS:我看到網(wǎng)上有一篇文章介紹Django實現(xiàn)訪問統(tǒng)計的,那個作者寫了一個方法,在每個接口里調(diào)用一次,看得我頭皮發(fā)麻
在中間件中注入Repo,然后每次請求都把IP、設(shè)備、請求路徑等數(shù)據(jù)保存在數(shù)據(jù)庫中。這樣看起來應該是會有一些影響性能的,不過考慮到博客網(wǎng)站的并發(fā)應該很小,帶來的性能損失應該可以忽略不計。(說白了就是懶)
后續(xù)有性能瓶頸時再來優(yōu)化吧~
模型定義
在StarBlog.Data/Models中新建一個VisitRecord.cs
為了節(jié)省篇幅,注釋啥的就不放了,具體代碼可見github
public class VisitRecord {
public int Id { get; set; }
public string Ip { get; set; }
public string RequestPath { get; set; }
public string? RequestQueryString { get; set; }
public string RequestMethod { get; set; }
public string UserAgent { get; set; }
public DateTime Time { get; set; }
}
寫個中間件
在StarBlog.Web/Middlewares中新建一個VisitRecordMiddleware.cs
public class VisitRecordMiddleware {
private readonly RequestDelegate _next;
public VisitRecordMiddleware(RequestDelegate requestDelegate) {
_next = requestDelegate;
}
public Task Invoke(HttpContext context, IBaseRepository<VisitRecord> visitRecordRepo) {
var request = context.Request;
var response = context.Response;
visitRecordRepo.InsertAsync(new VisitRecord {
Ip = context.Connection.RemoteIpAddress?.ToString().Split(":").Last(),
RequestPath = request.Path,
RequestQueryString = request.QueryString.Value,
RequestMethod = request.Method,
UserAgent = request.Headers.UserAgent,
Time = DateTime.Now
});
return _next(context);
}
}
這里有個地方要注
意的,我的visitRecordRepo是在Invoke方法中注入的,為什么不在構(gòu)造方法中注入呢?
因為AspNetCore中間件的構(gòu)造方法是Singleton的,所以只能注入Singleton方式的服務(wù),而FreeSQL的Repository是Scoped的,如果在構(gòu)造方法中注入就會報錯
所以只能在Invoke方法中注入~
使用中間件
編輯StarBlog.Web/Programs.cs,增加中間件配置
app.UseMiddleware<VisitRecordMiddleware>();
PS:本項目基于.Net6,Startup和Program合二為一了;如果是.NetCore3.1及以下版本,則是在Startup.cs中配置中間件。
效果
目前還沒有根據(jù)訪問記錄做分析,所以只能截個數(shù)據(jù)庫的圖片

OK,接下來可以根據(jù)這些數(shù)據(jù)來做分析了(后面管理后臺開發(fā)的部分再來寫)

浙公網(wǎng)安備 33010602011771號