ASP.NET Core 8.0 SignalR:连接成功但客户端未收到通知

问题描述 投票:0回答:1

我正在开发 ASP.NET Core 8.0 Web API 应用程序,并且我第一次尝试实现 SignalR 来实现实时通知。尽管成功连接到 SignalR 中心,但我无法在客户端接收任何通知,无论是在 Postman 还是自定义控制台应用程序中。我需要帮助来理解为什么未发送通知。

到目前为止我做了什么

  1. 已安装 SignalR 软件包:我已经安装了 Microsoft.AspNetCore.SignalR 软件包并设置了我的集线器。

  2. 创建了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);
}
  1. ClientNotificationDto 模型: ClientNotificationDto 模型的结构如下:
    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; }
    }

  1. 在 Program.cs 中配置 SignalR :我添加了 SignalR 服务并在 Program.cs 中映射了集线器:
services.AddSignalR();
app.MapHub<NotificationHub>("/notificationHub");
  1. 授权:我使用 [Authorize] 属性,因为需要 JWT 令牌身份验证。

  2. 创建了一个测试控制器:我创建了一个测试控制器来模拟发送通知:

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 日志,显示连接处于活动状态,但没有消息。

我尝试过的:

  • 验证是否正在调用NotificationHub方法并且应该发送消息。
  • 检查连接状态和 ping 日志,表明连接处于活动状态。
  • 使用 Postman 和自定义控制台应用程序进行测试,但都没有收到预期的消息。

客户端代码:

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);

然后客户端什么也没有收到。

我不知道为什么尽管连接成功,但客户端没有收到通知。我在设置或发送通知的方式中缺少什么吗?如何解决此问题并让通知显示在客户端中?

任何帮助或建议将不胜感激!

.net asp.net-web-api signalr signalr-hub asp.net-core-signalr
1个回答
0
投票

这个错误;弹出

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", ...);
© www.soinside.com 2019 - 2024. All rights reserved.