HttpRequest不会在冗长的请求上超时

时间:2022-03-15 08:03:30

I have the following Ajax call

我有下面的Ajax调用

function exampleAjax() {
    $('#loadingImage').show();

    var id = GetId();
    $.ajax({
        url: "../Controller/MyRequest?id=" + id,
        type: "GET",
        dataType: 'json',
        contentType: 'application/json; charset=utf-8',
        success: function (result) {
            if (result.success === true) {
                // Show Dialog Success
            }
            else {
                // Show Dialog Failure
            }
        },
        async: true,
        processData: false
    });
}

which calls below controller's method.

在控制器的方法下面调用。

public async Task<JsonResult> MyRequest(string teamId)
{
    bool success = false;
    try
    {
        HttpResponseMessage response = await client.GetAsync(fullUriEndpoint)
        if (!response.IsSuccessStatusCode)
            throw new Exception(response.ReasonPhrase);
        else
            success = true;

        return Json(new
        {
            success = success,
        }, JsonRequestBehavior.AllowGet);
    }
    catch (Exception ex)
    {
        return Json(new
        {
            success = success,
        }, JsonRequestBehavior.AllowGet);
    }
}

Because the request takes few minutes to process (this is totally fine, server needs to do a some processing that could take up to 5 minutes or more) then the client send back an exception although the task is still executed in the backend.

由于处理请求需要几分钟(这完全没问题,服务器需要进行一些可能长达5分钟或更长时间的处理),然后客户端发送回一个异常,尽管任务仍然在后端执行。

Is there a way I can manage this scenario without doing a fire and forget? I want to wait for the execution of this request until it gets completed.

有没有一种方法可以让我在不发生火灾和忘记的情况下管理这个场景呢?我希望等待这个请求的执行,直到它完成。

3 个解决方案

#1


1  

As an option you may build a kind of polling process:

作为一种选择,您可以构建一种轮询过程:

  1. Client sends a request for "long operation".
  2. 客户端发送“长操作”请求。
  3. Server starts the operation, gives it some id.
  4. 服务器启动操作,给它一些id。
  5. And immediately responds to the client that the operation has been started.
  6. 并立即回复客户操作已经启动。
  7. Then server listens for an API like GET /api/operation/:id to respond a status of given operation (done or in progress).
  8. 然后服务器侦听GET / API /operation/:id等API,以响应给定操作的状态(已完成或正在进行)。
  9. Client gets this pre-answer from (3) and run a timer, he requests the API from (4) every let's say 500ms until the operation is done or until N attempts are done.
  10. 客户端从(3)获取这个预应答并运行一个计时器,他从(4)请求API,假设每次500ms,直到操作完成或N次尝试完成。

Another option would be to provide bi-directional communication between server and client using WebSockets.

另一种选择是使用WebSockets在服务器和客户端之间提供双向通信。

#2


1  

Probably your best bet would be to use SignalR. So ignoring that you should't run long running processes on asp.net.. I would recommend using something that does what you need in a different and easier way. SignalR abstracts Ajax/WebSockets so all you have to do is make calls either way (client to server or server to client).

也许你最好的选择是使用信号量。所以忽略了你不应该在asp.net上运行长时间运行的进程。我建议你用一种不同的、更简单的方法来做你需要的东西。SignalR抽象了Ajax/WebSockets,所以你所要做的就是以任何一种方式进行调用(客户机到服务器或者服务器到客户机)。

Client to server (javascript):

客户端到服务器(javascript):

$.connection.myHub.StartProcess()

Server

服务器

public class MyHub : Hub
{
  public void StartProcess()
  {
    // DO WORK

    // Call Client!
    Clients().Client(id).ProcessFinished()
  }
}

Client (Javascript)

客户端(Javascript)

$.connection.myHub.ProcessFinished = function(){  
  console.log('Long process finished!');
}

#3


0  

Instead of using HTTP and long-polling, you could simply implement the scenario using websockets that allows persistent connections with simultaneous bi-directional communication. In fact, you could use one of the realtime APIs to implement your application like Firebase, PubNub, deepstream, etc.

与使用HTTP和长轮询不同,您可以简单地使用websockets实现该方案,该方案允许使用同时进行双向通信的持久连接。实际上,您可以使用一个realtime api来实现您的应用程序,如Firebase、PubNub、deepstream等。

#1


1  

As an option you may build a kind of polling process:

作为一种选择,您可以构建一种轮询过程:

  1. Client sends a request for "long operation".
  2. 客户端发送“长操作”请求。
  3. Server starts the operation, gives it some id.
  4. 服务器启动操作,给它一些id。
  5. And immediately responds to the client that the operation has been started.
  6. 并立即回复客户操作已经启动。
  7. Then server listens for an API like GET /api/operation/:id to respond a status of given operation (done or in progress).
  8. 然后服务器侦听GET / API /operation/:id等API,以响应给定操作的状态(已完成或正在进行)。
  9. Client gets this pre-answer from (3) and run a timer, he requests the API from (4) every let's say 500ms until the operation is done or until N attempts are done.
  10. 客户端从(3)获取这个预应答并运行一个计时器,他从(4)请求API,假设每次500ms,直到操作完成或N次尝试完成。

Another option would be to provide bi-directional communication between server and client using WebSockets.

另一种选择是使用WebSockets在服务器和客户端之间提供双向通信。

#2


1  

Probably your best bet would be to use SignalR. So ignoring that you should't run long running processes on asp.net.. I would recommend using something that does what you need in a different and easier way. SignalR abstracts Ajax/WebSockets so all you have to do is make calls either way (client to server or server to client).

也许你最好的选择是使用信号量。所以忽略了你不应该在asp.net上运行长时间运行的进程。我建议你用一种不同的、更简单的方法来做你需要的东西。SignalR抽象了Ajax/WebSockets,所以你所要做的就是以任何一种方式进行调用(客户机到服务器或者服务器到客户机)。

Client to server (javascript):

客户端到服务器(javascript):

$.connection.myHub.StartProcess()

Server

服务器

public class MyHub : Hub
{
  public void StartProcess()
  {
    // DO WORK

    // Call Client!
    Clients().Client(id).ProcessFinished()
  }
}

Client (Javascript)

客户端(Javascript)

$.connection.myHub.ProcessFinished = function(){  
  console.log('Long process finished!');
}

#3


0  

Instead of using HTTP and long-polling, you could simply implement the scenario using websockets that allows persistent connections with simultaneous bi-directional communication. In fact, you could use one of the realtime APIs to implement your application like Firebase, PubNub, deepstream, etc.

与使用HTTP和长轮询不同,您可以简单地使用websockets实现该方案,该方案允许使用同时进行双向通信的持久连接。实际上,您可以使用一个realtime api来实现您的应用程序,如Firebase、PubNub、deepstream等。