繁体   English   中英

ASP.NET Core 2.1 在一个schedule中调用Rest API

[英]ASP.NET Core 2.1 Calling Rest API in a schedule

我有这个 ASP.NET Core 2.1 web 应用程序。 管理员从下面的页面获取在线游戏代码。 选择游戏(Razer Gold Pin)、数量和 email 发送这些代码。

购买电话 Rest API。 购买次数有限制,一次最多可购买200次。

起初,买的东西不多,所以没有问题。 但是需求量增加了,当有1万、2万的采购量时,就需要在这个屏幕上采购几个小时。 我想知道我们是否可以在不在屏幕前等待调度的情况下进行大量购买?

在此处输入图像描述

这是 cshtml 中的 Javascript:

$("#btn_add").html(
                            '<span class="spinner-border spinner-border-sm" role="status" id="spinner" aria-hidden="true"></span> Loading...'
                        );
                        var selText = $("#validationCustom04").val();
                        var gameName = $("#validationCustom04 option:selected").text();
                        var quantity = $("#quantity").val();
                        var email = $("#email").val();
                        var price = $("#total").val();
                        var company = $("#validationCustom05").val();

                        if ($("#total").val() !== '') {

                            price = $("#total").val();

                        }

                        var serviceUrl = '/GameBanks/A101PinAsync?quantity=' + quantity + '&game=' + selText + '&email=' + email + '&prc=' + price + '&gameName=' + gameName + '&company=' + company;
                        $.ajax({
                            type: "GET",
                            url: serviceUrl,
                            dataType: 'json',
                            success: function (data) {
                                //alert(JSON.stringify(data));
                                ShowResult(data);
                                $("#spinner").remove();
                                $("#btn_add").html('Add');

                            }, error: function (xhr, status, error) {
                                $("#spinner").remove();
                                $("#btn_add").html('Add');

                                var errorMessage = xhr.responseText;

                                alert('Error - ' + errorMessage);
                            }

                        });

这是 controller 方法:

[HttpGet]
public async Task<IActionResult> A101PinAsync(int quantity, string game, string email, int prc, string gameName, string company)
{
    var price = 0;

    try
    {
        string result = null;
                
        var dList = new DemoList();

        if (prc > 0)
        {
            price = prc;
        }

        var games = new Game { Product = game, Quantity = quantity };

        var content = await games.CallGameAsync("Test", "12345", game, quantity, company);

        var deserializedResult = JObject.Parse(content);

        var root = JsonConvert.DeserializeObject<Root>(content);

        if ((string)deserializedResult["coupons"]?[0]?["Serial"] == null)
        {
            result = result + gameName + ":" + (string)deserializedResult["Message"] + "\n";
        }
        else
        {
            foreach (var coupon in root.coupons)
            {
                result = result + gameName + "  Serial:" + coupon.Serial + "  Pin:" + coupon.Pin + "\n";
            }
        }
               
        dList.gameList = result;
                
        // NLOG
        NLogPin(logger, User.Identity.Name, DateTime.Now, result, email);
                
        return new JsonResult(dList);
    }
    catch (Exception e)
    {
        // NLOG
        NLog(logger2, "OyunPalas " + e.Message, DateTime.UtcNow,0);
                
        return StatusCode(500,e.Message);
    }
}

下面是Web API的调用方法:

public class Game
{
    public string Username { get; set; }
    public string Password { get; set; }
    public string Product { get; set; }
    public int Quantity { get; set; }
    public string ShopNo { get; set; }

    private static readonly Logger logger2 = LogManager.GetLogger("exceptionFile");

    public async Task<string> CallGameAsync(string username, string password, string product, int quantity, string company)
    {
        try
        {
            HttpWebRequest request = null;
            
            request = (HttpWebRequest)WebRequest.Create("http://111.111.111.111:1907//api/v2/web/purchase");

            var svcCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password));
            
            request.Headers.Add("Authorization", "Basic " + svcCredentials);
            request.Method = "POST";
            request.KeepAlive = false;
            request.ContentType = "application/x-www-form-urlencoded";

            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("productCode", product),
                new KeyValuePair<string, string>("quantity", quantity.ToString()),
                new KeyValuePair<string, string>("shopNo", company),
                new KeyValuePair<string, string>("safeNo", company),
                new KeyValuePair<string, string>("cashierNo", company)
            });

            var urlEncodedString = await content.ReadAsStringAsync();

            using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
            {
                await streamWriter.WriteAsync(urlEncodedString);
            }

            var httpResponse = (HttpWebResponse) (await request.GetResponseAsync());

            var response = new HttpResponseMessage
            {
                StatusCode = httpResponse.StatusCode,
                Content = new StreamContent(httpResponse.GetResponseStream()),
            };

            //Read response
            var htmlResponse = await response.Content.ReadAsStringAsync();

            return htmlResponse;
        }
        catch (Exception e)
        {
            //NLOG
            NLog(logger2, "Test" + e.Message);
            throw;
        }
    }

    public void NLog(Logger logger, string user)
    {
        var sb = new StringBuilder();
        sb.AppendLine("Test: " + user);
        logger.Info(sb.ToString());
    }
}

我必须将产品(游戏类型)传递给工作。 我阅读了https://www.quartz-scheduler.net/documentation/quartz-3.x/tutorial/more-about-jobs.html#jobdatamap文档,但不完全了解如何在我的案例中使用。 我想知道我是否可以在结束时间之前从此页面停止/取消作业?

我真的很感激你能提供的任何帮助。 如果这个问题太愚蠢,我很抱歉,因为我没有这种安排的经验。

编辑:

我想到了这样的解决方案,但我不确定它是否可行。

  • 用户将在屏幕上输入他们想要购买的游戏数量以及他们的电子邮件地址。

  • 此数据将保存在包含此信息和 SQL 数据库中状态字段的表 (BulkRequest) 中。 (游戏:ABC,数量:20000,状态:0)

  • 一个 IHostedService 将从 BulkRequest 表中获取状态 = 0 的计划中的已保存数据,并在新表 (GameRequests) 中以 100 的倍数获取带有状态信息的保存请求。(游戏:ABC,数量:100,状态:0)

  • 另一个 IHostedService 将在 10 分钟内从 GameRequests 表中获取 status=0 的记录,并进行第 3 方 API 调用。 将响应写入另一个表(GameResponses),如果没有错误则设置状态=1。

  • 当所有请求完成后(status = 1),BulkRequest表中的status也会更新为1。

  • 第三个 IHostedService 将检查 BulkRequest 的状态,如果 status=1 那么第四个服务可能会准备一个文件并将响应发送到电子邮件。

我确实建议查看消息队列工具,例如 RabbitMQ。使用此架构,您将使用消息传递协议完成所有工作,而无需“调度”,并且将省略任何“x 分钟调度”。 它也更稳定,并且可以使用最佳实践标准来处理错误。 更重要的是,它是可扩展的,你甚至可以在不同的服务器上拥有多个 hostedServices 队列中的进程项目:

  • 注册请求后,向队列发送消息(发布)。
  • hostedService1 接收项目并处理它(消费)。 多个服务可以订阅处理请求。
  • hostedService1 可以自己完成所有工作,甚至可以使用相同的方法将某些部分分派给其他服务

您提出的解决方案是通过临时流程完成相同的工作。 事实上,你正在重新发明轮子。 希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM