增加Angular 2+和ASP.NET Core WebAPI应用程序的超时

时间:2019-03-05 09:57:09

标签: c# angular asp.net-core asp.net-core-webapi

在我的Angular 2+ / ASP.NET Core MVC WebAPI应用程序中,我从客户端UI到服务器进行了长时间运行的API调用。 30秒后请求超时。我想为此客户端或服务器端的特定API调用定义超时。

我只找到了全局配置服务器超时的方法,这不是我想要的,因为30秒的超时对于其他呼叫来说很好。我还找到了通过传递RxJS的timeout运算符来减少超时客户端的解决方案。但是,据我了解,这不适合增加延长超时时间?

如何设置此特定请求的超时时间? 30秒默认值是从哪里来的?

(该代码实际上并不重要,因为它是标准的API控制器和标准的Angular HTTP调用):

this.http.get('api/xyz').subscribe(d => { ... });

2 个答案:

答案 0 :(得分:2)

要解决超时问题,可以使用如下所示的RxJ中的timeout

传递给timeout运算符的时间

这里我要传递60秒的超时时间,所以60秒后如果服务器没有响应,则会抛出超时错误。

import ‘rxjs/add/operator/timeout’; 

...

this.http.get('api/xyz').timeout(60000).subscribe(d => { ... });

答案 1 :(得分:1)

看来,在不扩展HttpClientModule类的情况下,拦截器与各个请求进行通信的唯一预期方式是paramsheaders对象。

由于超时值为标量,因此可以安全地将其作为自定义标头提供给拦截器。

import { Inject, Injectable, InjectionToken } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { timeout } from 'rxjs/operators';

export const DEFAULT_TIMEOUT = new InjectionToken<number>('defaultTimeout');

@Injectable()
export class TimeoutInterceptor implements HttpInterceptor {
  constructor(@Inject(DEFAULT_TIMEOUT) protected defaultTimeout: number) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const timeoutValue = Number(req.headers.get('timeout')) || this.defaultTimeout;

    return next.handle(req).pipe(timeout(timeoutValue));
  }
}

可以在您的应用模块中对其进行配置,例如:

...
providers: [
  [{ provide: HTTP_INTERCEPTORS, useClass: TimeoutInterceptor, multi: true }],
  [{ provide: DEFAULT_TIMEOUT, useValue: 30000 }]
],  
...

然后使用自定义超时标头完成请求

http.get(..., { headers: new HttpHeaders({ timeout: `${20000}` }) });