Jas*_*SFT 9 c# signalr signalr.client asp.net-core-signalr azure-signalr
我正在尝试在ASP.NET Core 3.0 Blazor(服务器端)应用程序与Azure SignalR服务之间建立连接。最后,我将SignalR客户端(服务)注入到一些Blazor组件中,以便它们可以实时更新我的UI / DOM。
我的问题是,.StartAsync()在集线器连接上调用方法时,我收到以下消息:
响应状态代码不表示成功:404(未找到)。
该文件加载了我对SignalR服务的配置,包括URL,连接字符串,键,方法名称和集线器名称。这些设置在静态类中捕获,SignalRServiceConfiguration并在以后使用。
public static class BootstrapSignalRClient
{
public static IServiceCollection AddSignalRServiceClient(this IServiceCollection services, IConfiguration configuration)
{
SignalRServiceConfiguration signalRServiceConfiguration = new SignalRServiceConfiguration();
configuration.Bind(nameof(SignalRServiceConfiguration), signalRServiceConfiguration);
services.AddSingleton(signalRServiceConfiguration);
services.AddSingleton<ISignalRClient, SignalRClient>();
return services;
}
}
Run Code Online (Sandbox Code Playgroud)
public class SignalRServiceConfiguration
{
public string ConnectionString { get; set; }
public string Url { get; set; }
public string MethodName { get; set; }
public string Key { get; set; }
public string HubName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
public class SignalRClient : ISignalRClient
{
public delegate void ReceiveMessage(string message);
public event ReceiveMessage ReceiveMessageEvent;
private HubConnection hubConnection;
public SignalRClient(SignalRServiceConfiguration signalRConfig)
{
hubConnection = new HubConnectionBuilder()
.WithUrl(signalRConfig.Url + signalRConfig.HubName)
.Build();
}
public async Task<string> StartListening(string id)
{
// Register listener for a specific id
hubConnection.On<string>(id, (message) =>
{
if (ReceiveMessageEvent != null)
{
ReceiveMessageEvent.Invoke(message);
}
});
try
{
// Start the SignalR Service connection
await hubConnection.StartAsync(); //<---I get an exception here
return hubConnection.State.ToString();
}
catch (Exception ex)
{
return ex.Message;
}
}
private void ReceiveMessage(string message)
{
response = JsonConvert.DeserializeObject<dynamic>(message);
}
}
Run Code Online (Sandbox Code Playgroud)
我在将SignalR与.NET Core结合使用时经验丰富,因此您可以在.NET Core中添加SignalR,并Startup.cs使用该文件.AddSignalR().AddAzureSignalR()并在应用程序配置中映射集线器,并且以这种方式进行操作需要建立某些“配置”参数(即连接字符串)。
根据我的情况,从哪里HubConnectionBuilder获得连接字符串或用于对SignalR服务进行身份验证的密钥?
404消息是否可能是缺少键/连接字符串的结果?
Jas*_*SFT 10
好吧,事实证明文档在这里缺少关键信息。如果使用 .NET SignalR 客户端连接到 Azure SignalR 服务,则需要请求 JWT 令牌并在创建集线器连接时提供它。
如果您需要代表用户进行身份验证,则可以使用此示例。
否则,您可以使用 Web API(例如 Azure 函数)设置“/negotiate”端点,为您检索 JWT 令牌和客户端 URL;这就是我最终为我的用例所做的。可以在此处找到有关创建 Azure 函数以获取 JWT 令牌和 URL 的信息。
我创建了一个类来保存这两个值:
public class SignalRConnectionInfo
{
[JsonProperty(PropertyName = "url")]
public string Url { get; set; }
[JsonProperty(PropertyName = "accessToken")]
public string AccessToken { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我还在 my 内部创建了一个方法SignalRService来处理与 Azure 中 Web API 的“/negotiate”端点的交互、集线器连接的实例化以及使用事件 + 委托接收消息,如下所示:
public async Task InitializeAsync()
{
SignalRConnectionInfo signalRConnectionInfo;
signalRConnectionInfo = await functionsClient.GetDataAsync<SignalRConnectionInfo>(FunctionsClientConstants.SignalR);
hubConnection = new HubConnectionBuilder()
.WithUrl(signalRConnectionInfo.Url, options =>
{
options.AccessTokenProvider = () => Task.FromResult(signalRConnectionInfo.AccessToken);
})
.Build();
}
Run Code Online (Sandbox Code Playgroud)
这functionsClient是一个简单的强类型HttpClient预配置的基本 URL,FunctionsClientConstants.SignalR是一个静态类,带有附加到基本 URL 的“/negotiate”路径。
一旦我完成了这一切设置,我就调用了await hubConnection.StartAsync();它并“连接”了它!
毕竟,我设置了一个静态ReceiveMessage事件和一个委托如下(在同一个SignalRClient.cs):
public delegate void ReceiveMessage(string message);
public static event ReceiveMessage ReceiveMessageEvent;
Run Code Online (Sandbox Code Playgroud)
最后,我实现了ReceiveMessage委托:
await signalRClient.InitializeAsync(); //<---called from another method
private async Task StartReceiving()
{
SignalRStatus = await signalRClient.ReceiveReservationResponse(Response.ReservationId);
logger.LogInformation($"SignalR Status is: {SignalRStatus}");
// Register event handler for static delegate
SignalRClient.ReceiveMessageEvent += signalRClient_receiveMessageEvent;
}
private async void signalRClient_receiveMessageEvent(string response)
{
logger.LogInformation($"Received SignalR mesage: {response}");
signalRReservationResponse = JsonConvert.DeserializeObject<SignalRReservationResponse>(response);
await InvokeAsync(StateHasChanged); //<---used by Blazor (server-side)
}
Run Code Online (Sandbox Code Playgroud)
我已经向 Azure SignalR 服务团队提供了文档更新,当然希望这对其他人有所帮助!
| 归档时间: |
|
| 查看次数: |
475 次 |
| 最近记录: |