我正在开发 ASP.NET Core 8.0 Web API 应用程序,并且我第一次尝试实现 SignalR 来实现实时通知。尽管成功连接到 SignalR 中心,但我无法在客户端接收任何通知,无论是在 Postman 还是自定义控制台应用程序中。我需要帮助来理解为什么未发送通知。
到目前为止我做了什么:
已安装 SignalR 软件包:我已经安装了 Microsoft.AspNetCore.SignalR 软件包并设置了我的集线器。
创建了Hub和接口:我创建了一个NotificationHub类和一个INotificationHub接口,如下所示:
'''
public sealed class NotificationHub : Hub<INotificationHub>
{
public async Task SendNotification(string userId, ClientNotificationDto notification)
{
await Clients.User(userId).ReceiveNotification(notification);
}
public async Task SendNotificationToGroup(string groupName, string message)
{
await Clients.Group(groupName).ReceiveNotification(message);
}
public async Task AddToGroup(string groupName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
}
public async Task RemoveFromGroup(string groupName)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
}
public async Task SendNotificationToAll(string message)
{
await Clients.All.ReceiveNotification(message);
}
}
public interface INotificationHub
{
Task ReceiveNotification(string message);
Task ReceiveNotification(ClientNotificationDto notification);
Task SendNotification(string userId, ClientNotificationDto notification);
Task SendNotificationToGroup(string groupName, string message);
Task AddToGroup(string groupName);
Task RemoveFromGroup(string groupName);
Task SendNotificationToAll(string message);
}
public class ClientNotificationDto
{
public long Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public bool IsRead { get; set; }
public DateTimeOffset CreateDate { get; set; }
}
services.AddSignalR();
app.MapHub<NotificationHub>("/notificationHub");
授权:我使用 [Authorize] 属性,因为需要 JWT 令牌身份验证。
创建了一个测试控制器:我创建了一个测试控制器来模拟发送通知:
var notificationDto = new ClientNotificationDto
{
Id = 1,
Title = "Test Title",
Content = "Test Content",
IsRead = false,
};
await _hubContext.Clients.User(clientNotification.CustomerId).ReceiveNotification(notificationDto);
// Added for testing purposes
await _hubContext.Clients.All.ReceiveNotification("Hello");
问题:
当我触发控制器时,它执行成功。但是,当我使用 Postman 或自定义控制台应用程序连接到集线器时,我没有收到任何通知。
在Postman和控制台应用程序中,我看到消息Connected to wss://localhost:7159/notificationHub,表明连接成功。但是,没有收到任何消息。在控制台应用程序中,我每隔几秒就会看到 ping 日志,显示连接处于活动状态,但没有消息。
我尝试过的:
客户端代码:
class Program
{
static async Task Main(string[] args)
{
var token = "JWT_TOKEN";
var connection = new HubConnectionBuilder()
.WithUrl("https://localhost:7159/notification", options =>
{
options.AccessTokenProvider = () => Task.FromResult(token);
})
.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Debug);
logging.AddConsole();
})
.Build();
connection.On<ClientNotificationDto>("ReceiveNotification", notification =>
{
Console.WriteLine("Received notification event triggered");
try
{
if (notification != null)
{
Console.WriteLine($"Received notification: {notification.Title} - {notification.Content}");
}
else
{
Console.WriteLine("Received null notification.");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error processing received notification: {ex.Message}");
}
});
connection.Closed += async (error) =>
{
Console.WriteLine($"Connection closed: {error?.Message}");
await Task.Delay(5000);
try
{
await connection.StartAsync();
Console.WriteLine("Connection restarted.");
}
catch (Exception ex)
{
Console.WriteLine($"Error while restarting connection: {ex.Message}");
}
};
try
{
await connection.StartAsync();
Console.WriteLine("Connection started.");
}
catch (Exception ex)
{
Console.WriteLine($"Connection error: {ex.Message}");
}
Console.ReadLine();
}
}
如果我将以下行添加到我的主代码中:
await _hubContext.Clients.All.ReceiveNotification("hello");
在客户端,我正在监听消息,我收到以下错误:
fail: Microsoft.AspNetCore.SignalR.Client.HubConnection[57]
Failed to bind arguments received in invocation '(null)' of 'ReceiveNotification'.
System.IO.InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
---> System.Text.Json.JsonException: The JSON value could not be converted to SignalrTest.ClientNotificationDto. Path: $ | LineNumber: 0 | BytePositionInLine: 129.
at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.DeserializeAsObject(Utf8JsonReader& reader, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadAsObject(Utf8JsonReader& reader, JsonTypeInfo jsonTypeInfo)
at Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.BindType(Utf8JsonReader& reader, Type type)
at Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.BindTypes(Utf8JsonReader& reader, IReadOnlyList`1 paramTypes)
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.BindTypes(Utf8JsonReader& reader, IReadOnlyList`1 paramTypes)
at Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.ParseMessage(ReadOnlySequence`1 input, IInvocationBinder binder)
但是,如果我删除该行并仅包含:
var notificationDto = new ClientNotificationDto
{
Id = 1,
Title = "Test Title",
Content = "Test Content",
IsRead = false,
};
await _hubContext.Clients.User(clientNotification.CustomerId).ReceiveNotification(notificationDto);
然后客户端什么也没有收到。
我不知道为什么尽管连接成功,但客户端没有收到通知。我在设置或发送通知的方式中缺少什么吗?如何解决此问题并让通知显示在客户端中?
任何帮助或建议将不胜感激!
这个错误;弹出
Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
是因为接受类型 string
的客户端上的 ReceiveNotification 没有重载/类型。
两者都需要;
connection.On<string>("ReceiveNotification", ...);
connection.On<ClientNotificationDto>("ReceiveNotification", ...);