【发布时间】: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>
您会注意到promise 和hub 被定义为requirement_hub_start 和requirement_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