国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - 淺談ASP.NET Core中間件實現分布式 Session

淺談ASP.NET Core中間件實現分布式 Session

2020-05-18 13:48行動派Xdpie ASP.NET教程

這篇文章主要介紹了淺談ASP.NET Core中間件實現分布式 Session,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1.1. 中間件原理

1.1.1. 什么是中間件

中間件是段代碼用于處理請求和響應,通常多個中間件鏈接起來形成管道,由每個中間件自己來決定是否要調用下一個中間件。

淺談ASP.NET Core中間件實現分布式 Session

1.1.2. 中間件執行過程

舉一個示例來演示中間件的執行過程(分別有三個中間件:日志記錄、權限驗證和路由):當請求進入應用程序時,執行執行日志記錄的中間件,它記錄請求屬性并調用鏈中的下一個中間件權限驗證,如果權限驗證通過則將控制權傳遞給下一個中間件,不通過則設置401 HTTP代碼并返回響應,響應傳遞給日志中間件進行返回。

淺談ASP.NET Core中間件實現分布式 Session

1.1.3. 中間件的配置

中間件配置主要是用RunMapUse方法進行配置;簡單的中間件可以直接使用匿名方法就可以搞定,如下代碼:

?
1
2
3
4
5
app.Run(async (context,next) =>
    {
      await context.Response.WriteAsync("environment " + env);
      await next();
    });

如果想重用中間件,就需要單獨封裝到一個類中進行調用。

1.2. 依賴注入中間件

在實際項目中,中間件往往需要調用其它對象的方法。所以要創建對象之間的依賴,由于ASP.NET Core 內置的依賴注入系統,寫程序的時候可以創建更優雅的代碼。

首先需要要在IOC容器中注冊類,就是Startup類中的ConfigureServices方法中進行注冊,ConfigureServices方法會在Configure方法之前被執行。以便在用中間件時所有依賴都準備好了。

現在有一個Greeter類:

?
1
2
3
4
5
6
7
8
9
10
11
12
public class Greeter : IGreeter
{
  public string Greet()
  {
    return "Hello from Greeter!";
  }
}
 
public interface IGreeter
{
  string Greet();
}

第一步在ConfigureServices方法中進行注冊

?
1
2
3
4
public void ConfigureServices(IServiceCollection services)
{
  services.AddTransient<IGreeter, Greeter>();
}

筆者這里使用的是AddTransient進行注冊,該方法在每次請求時創建該類的新實例。可以選擇其它方法:AddSingleton,AddScoped或簡單的Add(所有在幕后前使用)。整個DI系統在官方文檔中有所描述。

在注冊了依賴項后,就可以使用它們了。IApplicationBuilder實例允許在Configure方法中有一個RequestServices屬性用于獲取Greeter實例。由于已經注冊了這個IGreeter接口,所以不需要將中間件與具體的Greeter實現相結合。

?
1
2
3
4
5
6
app.Use(async (ctx, next) =>
  {
    IGreeter greeter = ctx.RequestServices.GetService<IGreeter>();
    await ctx.Response.WriteAsync(greeter.Greet());
    await next();
  });

如果Greeter類有一個參數化的構造函數,它的依賴關系也必須在其中注冊ConfigureServices

中間件可以很容易解決依賴關系。可以向中間件構造函數添加其他參數:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MyMiddleware
{
  private readonly RequestDelegate _next;
  private readonly IGreeter _greeter;
 
  public MyMiddleware(RequestDelegate next, IGreeter greeter)
  {
    _next = next;
    greeter = greeter;
  }
 
  public async Task Invoke(HttpContext context)
  {
    await context.Response.WriteAsync(_greeter.Greet());
    await _next(context);
  }
}

或者,可以將此依賴關系添加到Invoke方法中:

?
1
2
3
4
5
public async Task Invoke(HttpContext context, IGreeter greeter)
{
  await context.Response.WriteAsync(greeter.Greet());
  await _next(context);
}

如果DI系統知道這些參數的類型,則在類被實例化時,它們將被自動解析。很簡單!

1.3. Cookies和session中間件

1.3.1. Session

HTTP是一個無狀態協議,Web服務器將每一個請求都視為獨立請求。并且不保存之前請求中用戶的值。

Session 狀態是ASP.NET Core提供的一個功能,它可以在用戶通應用訪問網絡服務器的時候保存和存儲用戶數據。由服務器上的字典和散列表組成,Session狀態通過瀏覽器的請求中得到,Session的數據保存到緩存中。

ASP.NET Core通過包含Session ID的Cookie來維護會話狀態,每個請求都會攜帶此Session ID。

Microsoft.AspNetCore.Session包中提供的中間件用來管理Session狀態。要啟用Session中間件,Startup類里面需要做以下幾個操作:

  1. 使用任何一個實現了IDistributedCache接口的服務來啟用內存緩存,
  2. 設置AddSession回調,由于AddSession是在Microsoft.AspNetCore.Session包內實現的,所以必須在Nuget中添加Microsoft.AspNetCore.Session包
  3. UseSession回調

具體示例代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System;
 
public class Startup
{
  public void ConfigureServices(IServiceCollection services)
  {
    services.AddMvc();
 
    // 添加一個內存緩存
    services.AddDistributedMemoryCache();
 
    services.AddSession(options =>
    {
      // 設置10秒鐘Session過期來測試
      options.IdleTimeout = TimeSpan.FromSeconds(10);
      options.Cookie.HttpOnly = true;
    });
  }
 
  public void Configure(IApplicationBuilder app)
  {
    app.UseSession();
    app.UseMvcWithDefaultRoute();
  }
}

上面代碼中IdleTimeout屬性用來確定用戶多久沒有操作時丟棄Session。此屬性和Cookie超時無關,通過Session中間件的每個請求都會重置超時時間。

1.3.2. Session保存到Redis中

實現分布式Session方法官方提供有Redis、Sql Server等。但是Sql Server效率對于這種以key/value獲取值的方式遠遠不及Redis效率高,所以這里筆者選用Redis來作示例實現分布式Session。

準備Redis

由于目前Redis還不支持windows,所以大家在安裝Redis的時候準備一臺linux操作系統,筆者這里的系統是ubuntu 16.04;下載及安裝方式可以參考官方示例。

安裝成功以后啟動Redis 服務,如果看到以下信息,就代表Redis啟動成功:

淺談ASP.NET Core中間件實現分布式 Session

相關配置

首先需要用Nuget安裝包Microsoft.Extensions.Caching.Redis,安裝成功以后就可以在app.csproj文件中可以看到。

淺談ASP.NET Core中間件實現分布式 Session

在Configure方法中添加app.UseSession();然后再ConfigureServices添加Redis服務

?
1
2
3
4
5
6
7
8
public void ConfigureServices(IServiceCollection services){
  services.AddDistributedRedisCache(options=>{
    options.Configuration="127.0.0.1"; //多個redis服務器:{RedisIP}:{Redis端口},{RedisIP}:{Redis端口}
    options.InstanceName="sampleInstance";
  });
  services.AddMvc();
  services.AddSession();
}

以上代碼中筆者只用一個Redis服務器來作測試,實際項目中需要多個Redis服務器;配置方法如:options.Configuration="地址1:端口,地址2:端口";,這里筆者并沒有給端口而是用的默認端口6379

完整代碼

Startup.cs

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Caching.Redis;
using Microsoft.Extensions.Caching.Distributed;
 
namespace app{ 
  public class Startup{   
    public Startup(IConfiguration configuration)   
    {     
      Configuration = configuration;   
    }
    public IConfiguration Configuration { get; }
 
    public void ConfigureServices(IServiceCollection services){          
      services.AddDistributedRedisCache(options =>{       
        options.Configuration = "127.0.0.1";       
        options.InstanceName = "sampleInstance";     
      });     
      services.AddMvc();     
      services.AddSession();   
    }
 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env){     
      if (env.IsDevelopment())
      {       
        app.UseDeveloperExceptionPage();     
      }     
      else     
      {       
        app.UseExceptionHandler("/Home/Error");     
      }
      app.UseSession();
      app.UseStaticFiles();
      app.UseMvc(routes =>{       
        routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");     
      });   
    
  }
}

HomeControler.cs

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class HomeController : Controller 
{   
  public IActionResult Index()   
  {     
    HttpContext.Session.Set("apptest",Encoding.UTF8.GetBytes("apptestvalue"));
    return View();   
  }
  public IActionResult ShowRedis()   
  {     
    byte[] temp;
    if(HttpContext.Session.TryGetValue("apptest",out temp))
    {       
      ViewData["Redis"]=Encoding.UTF8.GetString(temp);     
    }     
    return View();   
  }
}

Index頁面只做一件事給Session設置值:"apptestvalue",ShowRedis頁面顯示Session值。

ShowRedis.cshtml

?
1
Redis Session Value:ViewData["Redis"]

演示結果

現在開始運行頁面,首先直接進入到ShowRedis頁面,Session值顯示為空

淺談ASP.NET Core中間件實現分布式 Session

當點擊SetSessionValue以后,再次回到ShowRedis頁面,Session就值顯示出來了

淺談ASP.NET Core中間件實現分布式 Session

看到apptestvalue代表Session值已經存到Redis里面,怎樣證明apptestvalue值是從Redis里面取到呢?接下來就證明給大家看。

1.3.3. 實現分布Session

前面已經將Session保存到Redis中,但是大家不清楚這個值是否是真的保存到Redis里面去了還是在項目內存中;所以這里就實現在兩個不的應用程序(或兩臺不同的機器)中共享Session,也就是實現分布式Session,分布式即代表了不同的機器不同的應用程序,但往往有下面的一種尷尬的情況,就算是每個HTTP請求時都攜帶了相同的cookie值。

淺談ASP.NET Core中間件實現分布式 Session

造成這個的問題的原因是每個機器上面的ASP.NET Core的應用程序的密鑰是不一樣的,所以沒有辦法得到前一個應用程序保存的Session數據;為了解決這個問題,.NET Core團隊為提供了Microsoft.AspNetCore.DataProtection.AzureStorage和Microsoft.AspNetCore.DataProtection.Redis包將密鑰保存到Azure或Redis中。這里選擇將密鑰保存到Redis。

淺談ASP.NET Core中間件實現分布式 Session

利用Microsoft.AspNetCore.DataProtection.Redis包提供的PersistKeysToRedis重載方法將密鑰保存到Redis里面去。所以這里需要在ConfigureServices方法中添AddDataProtection()

?
1
2
3
4
var redis = ConnectionMultiplexer.Connect("127.0.0.1:6379");
  services.AddDataProtection()
    .SetApplicationName("session_application_name")
    .PersistKeysToRedis(redis, "DataProtection-Keys");

下面演示怎樣實現分布式Session

配置步驟

同時創建兩個項目,分別為app1和app2

添加Microsoft.AspNetCore.DataProtection.RedisStackExchange.Redis.StrongName包

淺談ASP.NET Core中間件實現分布式 Session

由于在同一臺機器上,ASP.NET Core程序默認啟動的時候端口為5000,由于app1已經占用了,所以將app2的啟端口設置為5001

淺談ASP.NET Core中間件實現分布式 Session

完整代碼

app1項目

Startup.cs

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Caching.Redis;
using Microsoft.Extensions.Caching.Distributed;
 
namespace app1{ 
  public class Startup{   
    public Startup(IConfiguration configuration)   
    {     
      Configuration = configuration;   
    }
    public IConfiguration Configuration { get; }
 
    public void ConfigureServices(IServiceCollection services){
      var redis = ConnectionMultiplexer.Connect("127.0.0.1:6379");
      services.AddDataProtection()
        .SetApplicationName("session_application_name")
        .PersistKeysToRedis(redis, "DataProtection-Keys");    
      services.AddDistributedRedisCache(options =>{       
        options.Configuration = "127.0.0.1";       
        options.InstanceName = "sampleInstance";     
      });     
      services.AddMvc();     
      services.AddSession();   
    }
 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env){     
      if (env.IsDevelopment())
      {       
        app.UseDeveloperExceptionPage();     
      }     
      else     
      {       
        app.UseExceptionHandler("/Home/Error");     
      }
      app.UseSession();
      app.UseStaticFiles();
      app.UseMvc(routes =>{       
        routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");     
      });   
    
  }
}

HomeControler.cs

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class HomeController : Controller 
{   
  public IActionResult Index()   
  {     
    HttpContext.Session.Set("app1test",Encoding.UTF8.GetBytes("app1testvalue"));
    return View();   
  }
  public IActionResult ShowRedis()   
  {     
    byte[] temp;
    if(HttpContext.Session.TryGetValue("app1test",out temp))
    {       
      ViewData["Redis"]=Encoding.UTF8.GetString(temp);     
    }     
    return View();   
  }
}

ShowRedis.cshtml

?
1
Redis Session Value:ViewData["Redis"]

app2項目

Startup.cs
配置同app1配置一樣。

HomeControler.cs

?
1
2
3
4
5
6
7
8
9
10
11
12
public class HomeController : Controller 
{   
  public IActionResult Index()   
  {     
    byte[] temp;
    if(HttpContext.Session.TryGetValue("app1test",out temp))
    {       
      ViewData["Redis"]=Encoding.UTF8.GetString(temp);     
    }
    return View();   
  }
}

Index.cshtml

?
1
ViewData["Redis"]

運行效果

app1 項目

首次打開進入ShowRedis頁面,Session值為空

淺談ASP.NET Core中間件實現分布式 Session

點擊SetSessionValue以后,再回到ShowRedis頁面:

淺談ASP.NET Core中間件實現分布式 Session

app2項目,直接在瀏覽器訪問:http://localhost:5001

淺談ASP.NET Core中間件實現分布式 Session

以上是用Redis實現分布式Session示例。 

1.4. 總結

本節講解了中間件的運行原理及配置過程,中間件之間對象依賴關系的配置和平時項目中常用到Session的配置問題。并在實際代碼展示了怎樣使用中間件實現分布式Session。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美视频一区 | 国产一区二区视频在线观看 | 日韩中文字幕一区二区三区 | 国产黄免费在线观看 | 国产综合在线视频 | 成人福利免费在线观看 | 国产免费久久 | 激情综合网五月婷婷 | 亚洲精品电影网在线观看 | 国产精品视频免费观看 | 先锋资源在线观看 | 欧美一级片免费播放 | 免费观看黄色大片 | 免费日韩| 中文字幕高清 | 啵啵影院午夜男人免费视频 | 亚洲福利一区二区 | 久久99精品久久久久久琪琪 | 3d动漫精品一区二区三区 | 午夜伦4480yy私人影院 | 91一区二区在线 | 在线看黄色毛片 | 国产 一区| 国产日韩欧美综合 | 国产精品久久久久久久浪潮网站 | 精品国产乱码久久久久久丨区2区 | 一级a性色生活片久久毛片 国产精品久久久久久久久久免费看 | 久久久一 | 不用播放器的免费av | 国产精品久久久久久久久久久久久久 | 午夜av影视| 99精品一区二区三区 | 日本丶国产丶欧美色综合 | 成人精品视频免费 | 欧美国产日韩精品 | 龙珠z普通话国语版在线观看 | 日本不卡一区二区三区在线观看 | 四房婷婷 | 久久影音 | 成人在线h | 日比视频网站 |