天天看點

使用.NET Core搭建分布式音頻效果處理服務(六)讓Middleware自動Invoke

使用.NET Core搭建分布式音頻效果處理服務(六)讓Middleware自動Invoke

為何要用中間件來實作音頻處理的監聽服務

當然也可以使用Startup來進行服務的自啟動,或者也可以使用quartz定時排程任務來啟動音頻服務,大家随意。

筆者認為使用中間件的目的,是為了分離應用和服務,也是一種解耦手段。

我們知道,在NETCORE中的中間件,有點類似像AOP的一種實作形式,他的調用方式是通過Request=>Middleware=>next=>custom logic=>Response。我們可以用來做日志記錄、權限驗證、事物處理,多個中間件形成一個處理管道,甚至可以實作自定義的MVC和依賴注入。

使用.NET Core搭建分布式音頻效果處理服務(六)讓Middleware自動Invoke

建立一個中間件

為了便于區分,我們擴充一個名為“MediaHandlers”的IApplicationBuilder

1     public static class MediaHandlers
 2     {
 3         public static IApplicationBuilder UseMediaAudioHandlerMiddleware(this IApplicationBuilder builder,
 4             MediaAudioOptions options)
 5         {
 6             if (builder == null)
 7                 throw new ArgumentNullException(nameof(builder));
 8 
 9             return builder.UseMiddleware<MediaAudioMiddleware>(options);
10         }
11     }      

再建立一個名為“MediaAudioMiddleware”的中間件,其實就是一個實作類,但需要傳遞對象RequestDelegate做請求代理。

并且,我們将在中間件中實作依賴注入,而中間件的依賴注入卻無法通過構造函數的方式進行注入,需要通過Invoke來實作依賴注入,完整代碼如下:

1 public async Task Invoke(HttpContext context,
 2             IDataOpService iDataOpService,
 3             ICacheAsyncService iCacheAsyncService,
 4             IMsgBusService imsgBusService,
 5             IHostingEnvironment iHostingEnvironment)
 6         {
 7             _dataOpService = iDataOpService;
 8             _iMsgBusService = imsgBusService;
 9             _iCacheAsyncService = iCacheAsyncService;
10             _ihostingEnvironment = iHostingEnvironment;
11 
12             await _next(context);
13         }      

跟之前的控制器注入的内容類型是一樣的。然後我們再來看看構造函數中需要實作的一些事情:

public MediaAudioMiddleware(RequestDelegate next, MediaAudioOptions options)
        {
            _next = next;

            Task.Factory.StartNew(() =>
            {
                Thread.Sleep(3 * 1000);
                //...需要自定義啟動的方法
            });
        }          

構造函數中預設必須傳遞RequestDelegate類型參數,用于委托執行Request之後Response之前的代理。

将需要啟動的服務已子任務(子線程)的方式交給Task工廠進行自行管理,再次分離了主管道請求應用。

但是,預設這個中間件是不會自動啟動的。。。因為沒有建立一個請求管道。

強制建立一個請求管道

筆者的思路是,通過httpclient請求主管道中的一個任意的API接口(比如你自定義實作的伺服器資訊接口),進而強制實作該請求管道的所有事情,比如循環,比如監聽等等。參考如下:

1                 using (var httpClient = new HttpClient())
 2                 {
 3                     httpClient.BaseAddress = new Uri($"{General.LocalHostUrl}/Info");
 4                     var r = httpClient.GetAsync(httpClient.BaseAddress).Result;
 5                     if (!r.ToString().Contains("200")) return;
 6                     Console.WriteLine("MediaAudioMiddleware Running");
 7                     var mediaHandler = new AudioHandlerWorkUnit(iDataOpService: _dataOpService,
 8                         iCacheAsyncService: _iCacheAsyncService,
 9                         imsgBusService: _iMsgBusService,
10                         iHostingEnvironment: _ihostingEnvironment,
11                         millsSeconds: options.MillsSeconds
12                     );
13                     mediaHandler.DoStart();
14                 }      

當然,需要在指令參數中(或前置參數中限制該管道隻建立一次),也許筆者的實作方式欠妥,如果你有更好的方法,歡迎交流。

感謝閱讀

繼續閱讀