结合使用SignalR和Web API来返回已完成的任务

时间:2019-01-13 19:37:34

标签: c# asp.net-mvc asp.net-web-api signalr signalr-hub

我正在寻求开发类似于TripAdvisor的工作原理的Web api / mvc应用程序,因为您可以选择开始日期和结束日期,并且页面会根据来自不同第三方API的响应动态更新。

某些API将在一秒钟内响应,而其他API可能需要5秒钟。因此,当任务完成时,我想用最新数据更新URL。

我首选使用SignalR和Web API的方法吗?

如果有人可以提供任何很棒的示例,我从未使用过SignalR。

我的出发点是这段代码已经可以发送请求了

  public class AvailabilityController : ApiController
  {
    [Route("test")]
    [HttpGet]
    public IHttpActionResult Get()
    {
        List<TimeoutException> TimeoutExceptions = new List<TimeoutException>();
        List<OperationCanceledException> OperationCanceledExceptions = new 
        List<OperationCanceledException>();
        List<Exception> Exceptions = new List<Exception>();
        List<AggregateException> AggregateExceptions = new List<AggregateException>();

        List<Models.Channel.IChannel> channels = new List<Models.Channel.IChannel>();            
        channels.Add(new Models.Channel.DummyChannelName());            

        var tasks = new List<Task>();
        var cts = new CancellationTokenSource();
        cts.CancelAfter(100);

        foreach (Models.Channel.IChannel channel in channels)
        {
            try
            {                    
                tasks.Add(Task.Run(() =>
                { 
                    channel.Data = channel.RequestOffers(new Models.Request.AvailabilityRequest()).Result;
                    cts.Token.ThrowIfCancellationRequested();

                }, cts.Token));

            }                
            catch(Exception ex)
            {
                Exceptions.Add(ex);
            }

        }
        try
        {                
            Task.WaitAll(tasks.ToArray(), cts.Token);                                
        }            
        catch (OperationCanceledException tc)
        {
            OperationCanceledExceptions.Add(tc);
        }            
        catch (Exception ex)
        {
            Exceptions.Add(ex);
        }
    }
  }

1 个答案:

答案 0 :(得分:0)

您可以按照以下方式配置集线器:

public class FooHub : Hub
{

}

,然后通过DI和IHubContext在控制器中使用此集线器:

class Foocontroller:controller
  {
   private readonly IHubContext<FooHub> _fooHubContext;

  public Foocontroller(IHubContext<FooHub> fooHubcontext)
  {
    _fooHubContext= fooHubcontext;
  }
  }

并在您的操作方法中使用Task.WaitAny(您的任务):

[Route("test")]
[HttpGet]
public async Task<IHttpActionResult> Get()
{
   int taskIndex = Task.WaitAny(your tasks);

string jsonFormat= JsonConvert.SerializeObject(yourFinishedTaskDataClass, Formatting.Indented,
                  new JsonSerializerSettings
                  {
                      ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                  });

    await _chatHubContext.Clients.All.SendAsync("your receiver method name", jsonFormat);
}

和查看页面:

<script type="text/javascript" src="js/signalr.min.js"></script>
 var connection = new signalR.HubConnectionBuilder()
            .withUrl('/FooHub')
            .build();

 connection.on('your receiver method name', function (message) {
           var g = JSON.parse(message);
            console.log(g);
        });