.net core Blazor未接收服务器端创建的信号器
在许多教程、示例之后,下面的示例我在服务器端调用,但客户端不接收,有时有效,有时无效(比有效的多) 本来应该很简单,但事实并非如此,任何建议都会帮我大忙 服务器端.net core Blazor未接收服务器端创建的信号器,.net-core,websocket,signalr,blazor,signalr.client,.net Core,Websocket,Signalr,Blazor,Signalr.client,在许多教程、示例之后,下面的示例我在服务器端调用,但客户端不接收,有时有效,有时无效(比有效的多) 本来应该很简单,但事实并非如此,任何建议都会帮我大忙 服务器端 public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { ge
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
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)
{
services.AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
var connection = @"data source=comandai.database.windows.net;initial catalog=HojeTaPago;persist security info=True;user id=Comandai;password=Ck@21112009;MultipleActiveResultSets=True;";
services.AddDbContext<ComandaiContext>(options => options.UseSqlServer(connection));
services.AddSignalR(options => options.KeepAliveInterval = TimeSpan.FromSeconds(5));
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" });
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "HojeTaPago API", Version = "v1" });
c.AddSecurityDefinition("basic", new OpenApiSecurityScheme
{
Name = "Authorization",
Type = SecuritySchemeType.Http,
Scheme = "basic",
In = ParameterLocation.Header,
Description = "Basic Authorization header using the Bearer scheme."
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "basic"
}
},
new string[] {}
}
});
});
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder.AllowAnyMethod().AllowAnyHeader()
.AllowCredentials();
}));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseResponseCompression();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "HojeTaPago API V1");
c.RoutePrefix = string.Empty;
});
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseAuthorization();
app.UseMiddleware<AuthenticationMiddleware>();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<NovoPedidoHub>("/novopedidohub");
endpoints.MapControllers();
});
}
}
客户端-Blazor
await _novoPedidoContext.Clients.All.SendAsync("NovoPedido", ListaComandaItem);
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddBlazoredLocalStorage();
services.AddBootstrapCss();
services.AddTransient<HubConnectionBuilder>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
公共类启动
{
公共启动(IConfiguration配置)
{
配置=配置;
}
公共IConfiguration配置{get;}
//此方法由运行时调用。请使用此方法将服务添加到容器中。
//有关如何配置应用程序的更多信息,请访问https://go.microsoft.com/fwlink/?LinkID=398940
public void配置服务(IServiceCollection服务)
{
services.AddRazorPages();
AddServerSideBlazor();
AddBlazoredLocalStorage();
services.AddBootstrapCss();
services.AddTransient();
}
//此方法由运行时调用。请使用此方法配置HTTP请求管道。
public void配置(IApplicationBuilder应用程序、IWebHostEnvironment环境)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
其他的
{
app.UseExceptionHandler(“/Error”);
//默认的HSTS值为30天。您可能希望在生产场景中更改此值,请参阅https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(端点=>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage(“/_主机”);
});
}
}
我打电话给
protected override async Task OnInitializedAsync()
{
DataService dataService = new DataService();
PedidosParaAceitar = new List<Comanda>(await dataService.BuscarComandasAbertas());
connection = _hubConnectionBuilder.WithUrl(dataService.servidor + "novopedidohub",
opt =>
{
opt.Transports = HttpTransportType.WebSockets;
opt.SkipNegotiation = true;
}).Build();
connection.On<List<ComandaItem>>("NovoPedido", async lista =>
{
var idEstabelecimento = await localStorage.GetItemAsync<int>("IdEstabelecimento");
if (lista.FirstOrDefault().Comanda.IdEstabelecimento == idEstabelecimento)
{
if (PedidosParaAceitar == null)
PedidosParaAceitar = new List<Comanda>();
if (PedidosParaAceitar.Count(x => x.Id == lista.FirstOrDefault().IdComanda) > 0)
foreach (var comandaitem in lista)
{
PedidosParaAceitar.FirstOrDefault(x => x.Id == lista.FirstOrDefault().IdComanda).ComandaItem.Add(comandaitem);
}
else
PedidosParaAceitar.Add(await dataService.BuscarComandaAberta(lista.FirstOrDefault().IdComanda));
StateHasChanged();
}
});
await connection.StartAsync();
}
受保护的重写异步任务OnInitializedAsync()
{
DataService DataService=新的DataService();
pedidosparaacetar=新列表(等待dataService.BuscarComandasAbertas());
连接=_hubConnectionBuilder.WithUrl(dataService.servidor+“novopedidohub”,
选择=>
{
opt.Transports=HttpTransportType.WebSockets;
opt.SkipNegotiation=true;
}).Build();
connection.On(“NovoPedido”,异步lista=>
{
var idEstabelecimento=await localStorage.GetItemAsync(“idEstabelecimento”);
if(lista.FirstOrDefault().Comanda.IdEstabelecimento==IdEstabelecimento)
{
如果(PEDIDOSPALACETAR==null)
Peddosparaaceitar=新列表();
如果(peddosparaaceitar.Count(x=>x.Id==lista.FirstOrDefault().IdComanda)>0)
foreach(列表A中的var comandaitem)
{
pedidosparaacetar.FirstOrDefault(x=>x.Id==lista.FirstOrDefault().IdComanda.ComandaItem.Add(ComandaItem);
}
其他的
Add(wait dataService.BuscarComandaAberta(lista.FirstOrDefault().IdComanda));
StateHasChanged();
}
});
等待连接。StartAsync();
}
您没有在标签中指定这是客户端(WASM)还是服务器端Blazor 在查看问题时,我注意到
ConfigureServices
中有一行:
services.AddServerSideBlazor();
因此,您正试图使用signar,一个来自服务器的客户端通信库。在服务器端Blazor中,所有C代码都在服务器上运行。在这方面,signar是冗余的,因为Blazor已经使用它在客户端和服务器之间进行通信
幸运的是,我最近真的写了一个应用程序来测试这一点。我创建了一个服务器端Blazor应用程序,并编写了以下服务:
公共类通话服务
{
公共广播服务
{
历史=新列表();
}
更改{get;set;}时的公共操作
//通知所有用户新消息
公共任务SendAsync(字符串消息)
{
//载入史册
添加(消息);
//确保仅显示最后10个
如果(history.Count>10)history.RemoveAt(0);
OnChange.Invoke(消息);
返回Task.FromResult(0);
}
私有只读列表历史记录;
公共IReadOnlyList GetHistory()=>history;
}
然后我在服务器上将其注册为一个单例(所有客户端使用相同的服务)
在Startup.cs
中的ConfigureServices()
方法:
services.AddSingleton<TalkService>();
聊天服务当然是一个基本的“聊天”示例。它是一个单实例,因此引用它的所有页面/客户端都使用相同的实例。该服务有一个简单的事件OnChange
,客户机(如索引页)可以通过该事件监听其他地方的更改
此应用程序不需要SignalR,因为它在服务器端已经“存在”
演示应用程序
演示应用程序还有一个后台服务,可以生成时间信息。我将此推送到GitHub以提供帮助:
您没有在标签中指定这是客户端(WASM)还是服务器端Blazor 在查看问题时,我注意到
ConfigureServices
中有一行:
services.AddServerSideBlazor();
因此,您正试图使用signar,一个来自服务器的客户端通信库。在服务器端Blazor中,所有C代码都在服务器上运行。在这方面,signar是冗余的,因为Blazor已经使用它在客户端和服务器之间进行通信
幸运的是,我最近真的写了一个应用程序来测试这一点。我创建了一个服务器端Blazor应用程序,并编写了以下服务:
公共类通话服务
{
公共广播服务
{
历史=新列表();
}
公共行动