我有一个在Azure应用服务上运行的Web应用。它是由SignalR服务支持的Blazor服务器。我还有一些由Azure函数执行的后台处理。完成该功能后,我希望通过SignalR向Web应用程序发送通知。
我通过在Azure函数上启用SignalR输出绑定实现了这一点。只要我将函数App视为SignalR集线器(即Blazor服务器创建函数App的HubConnection)-我就能够接收从Azure函数发送的消息。
但是,在上面的场景中,我必须配置第二个在无服务器模式下运行的SignalR实例。所以我在想,有没有其他方法可以让我绕过无服务器设计?我是否可以仅在Azure函数中使用SignalR客户端(并手动创建第一个SignalR服务的HubConnection)?或者对于Azure函数来说,这是不是有点太重了?我最好以另一种方式创建推送通知(例如,Blazor服务器对Service Bus队列做出反应,然后然后通过SignalR发送消息)?
推荐答案所以我想出了两个可能的答案。在第一个版本中,我将SignalR客户端添加到Azure函数:
[Function("SignalRFunction")] public static async Task RunAsync([ServiceBusTrigger("import-request")] string json, FunctionContext context) { var conn = new HubConnectionBuilder() .WithUrl( "localhost:5001" ) .Build(); await conn.StartAsync(); await conn.InvokeAsync( "Broadcast", "me", "some message" ); }这将连接到我的Blazor服务器上的集线器,并调用我的ImportHub上的广播消息:
public class ImportHub : Hub { public const string HubUrl = "/import"; public async Task Broadcast(string username, string message) { await Clients.All.SendAsync("Broadcast", username, message); } } 但使用此方法,我将为每个函数调用创建一个SignalR连接。可能不是最好的计划。我可以将conn转换为static对象(就像您可能对HttpClient所做的那样),但我仍然需要调用StartAsync()。我不确定HubConnection的最佳实践是什么。相反,我选择了答案2--Azure函数向Blazor服务器发出API调用。下面是我现在的函数:
[Function("SignalRFunction")] public static async Task RunAsync([ServiceBusTrigger("import-request")] string json, FunctionContext context) { var client = RestService.For<IImportHubApi>( "localhost:5001" ); await client.Broadcast("me", json); }对于客户端,我使用的是Refit:
public interface IImportHubApi { [Get("/api/broadcast")] Task Broadcast( string user, string message ); }在我的Blazor服务器上,我有以下API控制器:
[Route("api/broadcast")] [ApiController] public class BroadcastController : ControllerBase { private readonly IHubContext<ImportHub> _hub; public BroadcastController(IHubContext<ImportHub> hub) { _hub = hub; } [HttpGet] public async Task Get(string user, string message) { await _hub.Clients.All.SendAsync("Broadcast", user, message); } }因此,我认为这允许我的Azure功能进行扩展(如果它是相关的),而不必担心在使用One SignalR服务(默认模式)的同时管理连接。
然而,这是否是一个好主意(从安全角度来看)则是另一个问题。我认为,只要推送通知不是用来做坏事的(例如,用来刷新显示,而不是用来启动某个进程),那么问题就是确保我的服务器代码只使用通知来提示用户界面刷新。
我们确实有一个API服务器在App Service上运行。因此,我可以将此API调用移到那里,并将其放在防火墙(API管理)之后。这样,只能在VPC内进行广播。我假设我可以锁定ImportHub,因此您必须首先进行身份验证。
但我感兴趣的是其他人可能会说些什么。欢迎任何建议!
更多推荐
与Blazor服务器和Azure功能共享SignalR服务
发布评论