【问题标题】:Why am I getting no data from my Azure SignalR Service back to my KendoUI Grid?为什么我的 Azure SignalR 服务没有数据返回到我的 KendoUI Grid?
【发布时间】:2021-10-06 13:56:46
【问题描述】:

我在我的 ASP.NET Core 5 应用程序中使用了 KendoUI Grid。网格启用了 SignalR,我的应用程序托管在 Azure 中。我还使用 Azure SignalR 服务来处理文档中推荐的集线器。

我有 4 个集线器为我的 4 个不同的网格供电,但似乎它们都没有从 Azure 中的 SignalR 服务接收数据,我不知道出了什么问题。网格似乎已加载,缺少数据,我可以在控制台中使用 signalR 看到协商结果,它们返回 200 OK。但是,只是没有返回任何数据。

我不确定这是否与我设置应用程序或 Azure SignalR 服务的方式有关。

这是我在应用程序中实现 Azure SignalR 服务的方式。

Startup.cs (ConfigureServices)

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{

    var mvcBuilder = services.AddControllersWithViews(options => {
        var policy = new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .Build();
        options.Filters.Add(new AuthorizeFilter(policy));                
    });

    mvcBuilder.AddMicrosoftIdentityUI().AddJsonOptions(options =>
    {
        //Use the default property (Pascal) casing.
        options.JsonSerializerOptions.PropertyNamingPolicy = null;
    });

    services.AddRazorPages();

    services.AddSignalR(options => {
         //Debug only
         options.EnableDetailedErrors = true;
    }).AddAzureSignalR()
        .AddJsonProtocol(options =>
        {
            //Prevents signalr converting all text to lower case.
            options.PayloadSerializerOptions.PropertyNamingPolicy = null;
        });            

    //Kendo
    services.AddKendo();
    services.AddHealthChecks();
}

Startup.cs(配置)

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //Localization needed for date formats on datepickers
    var supportedCultures = new[] {
        new CultureInfo("en-GB")
    };

    //Localization set to En GB for datetime using the above supported cultures
    app.UseRequestLocalization(new RequestLocalizationOptions
    {
        DefaultRequestCulture = new RequestCulture("en-GB"),
        SupportedCultures = supportedCultures,
        SupportedUICultures = supportedCultures
    });
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/healthcheck");
        endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
    app.UseAzureSignalR(endpoints =>
    {                
        endpoints.MapHub<RequirementHub>("/requirementHub");
        endpoints.MapHub<PositionHub>("/positionHub");
        endpoints.MapHub<FixtureHub>("/fixtureHub");
        endpoints.MapHub<NewswireHub>("/newswireHub");
    });
}

我正在使用最新版本的客户端库中安装的 SignalR。

libman.js

{
  "provider": "unpkg",
  "library": "@microsoft/signalr@latest",
  "destination": "wwwroot/vendor/signalr/",
  "files": [
    "dist/browser/signalr.js",
    "dist/browser/signalr.min.js"
  ]
},

我的每个使用 SignalR 的网格都有集线器控制器。我已经展示了其中一个集线器控制器的代码,但它们的结构完全相同,唯一改变的是它们从中获取数据的存储库的名称。

需求中心

using MyCompany.Data;
using MyCompany.Repo;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace MyCompany.UI.Hubs
{
    public class RequirementHub : Hub
    {
        private readonly IRepository<Requirement> _requirement;

        public RequirementHub(IRepository<Requirement> requirement)
        {
            _requirement = requirement;
        }
        public override Task OnConnectedAsync()
        {
            Groups.AddToGroupAsync(Context.ConnectionId, GetGroupName());
            return base.OnConnectedAsync();
        }
        public override Task OnDisconnectedAsync(Exception e)
        {
            Groups.RemoveFromGroupAsync(Context.ConnectionId, GetGroupName());
            return base.OnDisconnectedAsync(e);
        }        
        public IEnumerable<Requirement> Read()
        {
            var data = _requirement.GetAll();
            return data;
        }        
        public async Task Update(Requirement model)
        {
            await _requirement.UpdateAsync(model);
            await Clients.OthersInGroup(GetGroupName()).SendAsync("update", model);
            
        }
        public string GetGroupName()
        {
            return GetRemoteIpAddress();
        }
        public string GetRemoteIpAddress()
        {
            return Context.GetHttpContext()?.Connection.RemoteIpAddress.ToString();
        }
    }
}

现在这将我们带到了网格本身。这是需求网格的代码,同样,有 4 个网格,它们的结构都相同,但名称不同,并引用了各自的中心。

Home.cshtml

<div id="requirement-grid"></div>

<script>
    $('#requirement_grid').kendoGrid({
        dataSource: {
             type: "signalr",
        autoSync: true,
        pageSize: 20,
        sort: [
            {
                field: "Id",
                dir: "desc"
            }
        ],
        schema: {
            model: {
                id: "Id",
                fields: {
                    "Id": {
                        editable: false,
                        nullable: true
                    }
                }
            }
        },
        transport: {
            signalr: {
                promise: requirement_hub_start,
                hub: requirement_hub,
                server: {
                    read: "read",
                    update: "update",
                    create: "create",
                    destroy: "destroy"
                },
                client: {
                    read: "read",
                    update: "update",
                    create: "create",
                    destroy: "destroy"
                }
            }
        },       
        autoBind: true,
        reorderable: true,
        sortable: true,
        pageable: {
            pageSize: 30,
            refresh: true
        },
        columns: [
            {
                field: "Id"
            }
        ]
    });
</script>

您会注意到promisehub 被定义为requirement_hub_startrequirement_hub,它们的代码位于其自己的JavaScript 文件中:

hubs.js

//Hub URL
var requirement_url = "/requirementHub";
var fixture_url = "/fixtureHub";
var position_url = "/positionHub";
var newswire_url = "/newswireHub";

//Connection Builder
var requirement_hub = new signalR.HubConnectionBuilder().withUrl(
    requirement_url, {
    transport: signalR.HttpTransportType.LongPolling
}).build();
var position_hub = new signalR.HubConnectionBuilder().withUrl(
    position_url, {
    transport: signalR.HttpTransportType.LongPolling
}).build();
var fixture_hub = new signalR.HubConnectionBuilder().withUrl(
    fixture_url, {
    transport: signalR.HttpTransportType.LongPolling
}).build();
var newswire_hub = new signalR.HubConnectionBuilder().withUrl(
    newswire_url, {
    transport: signalR.HttpTransportType.LongPolling
}).build();
//Hub Start
var position_hub_start = position_hub.start({
    json: true
});
var requirement_hub_start = requirement_hub.start({
    json: true
});
var fixture_hub_start = fixture_hub.start({
    json: true
});
var newswire_hub_start = newswire_hub.start({
    json: true
});

我查看了文档并将我的 SignalR 服务连接字符串放在我的 appsettings.json 中(直到我可以让它工作):

appsettings.json

 "Azure": {
    "SignalR": {
      "ConnectionString": "Endpoint=https://mycompanysignalr.service.signalr.net;AccessKey=xxx=;Version=1.0;",
      "Enabled": "true"
    }
  }

此外,我已确保在我的 Azure Web 应用程序中打开 Web 套接字,这是文档的另一项建议。在这一点上我有点困惑,我已经完成了 100 次设置,但我看不到任何可能阻止数据返回的明显内容。

我是否需要执行其他步骤或我做错了什么?以前有人遇到过这个问题吗?

【问题讨论】:

    标签: asp.net-core kendo-ui signalr


    【解决方案1】:

    请检查您的appsettings.json 中的Signalr ConnectionStrings。您可以从 azure 门户复制并替换它,然后尝试。

    以上建议是考虑你是否从开发环境到生产环境使用了不同的Signalr ConnectionStrings,导致了这个问题。

    此外,您使用的是什么定价层?如果您使用免费层,azure signalr 服务将限制您的使用。

    会这样,你一开始没问题,程序正常,超过限制,程序就会异常。第二天开始时,可​​以使用一段时间。这是免费定价层的限制。

    【讨论】:

      猜你喜欢
      • 2014-06-09
      • 1970-01-01
      • 2012-09-07
      • 2013-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-09
      相关资源
      最近更新 更多