向我的 Xamarin 应用程序聊天添加实时功能时抛出 System.InvalidOperationException
Adding real time functionality to my Xamarin app chat is throwing System.InvalidOperationException
我创建了一个带有聊天和 API 的 Xamarin 应用程序来存储它的数据,移动应用程序每 3 分钟向 api 请求聊天消息。
我决定按照评论中的建议使用 SignalR:
-将其添加到我的 CongifureService 中,如图所示:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<HostelContext>(opt =>
opt.UseSqlServer(Configuration.GetConnectionString("HostelContext")));
services.AddCors();
services.AddControllers();
services.AddAuthentication("BasicAuthentication")
.AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", null);
services.AddScoped<IUsersService, UsersService>();
services.AddScoped<IConversationsService, ConversationsService>();
services.AddScoped<IMessagesService, MessagesService>();
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "HostelApi", Version = "v1" });
});
services.AddSignalR();
}
- 添加端点进行配置,如图所示:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<ChatHub>("/chatHub");
});
-将 Class 添加到我的 api 项目中名为 Hub
的新文件夹中
-这是中心 class:
//[Authorize]
public class ChatHub : Hub
{
public async Task SendMessage(Message message)
{
//await Clients.All.SendAsync("ReceiveMessage", message);
await Clients.All.SendAsync("ReceiveMessage" + message.ConversationId, message);
//await Clients.Users(destinationUserIdList).SendAsync("ReceiveMessage" + message.ConversationId, message);
}
}
在我的 Xamarin 应用中:
- 添加的集线器服务:
-这是集线器服务 Class:
class HubService : IHubService
{
public HubConnection HubConnection { get; }
public HubService()
{
HubConnection = new HubConnectionBuilder()
.WithUrl($"https://10.0.2.2:5001/chatHub")
.Build();
}
public async Task Connect()
{
await HubConnection.StartAsync().ConfigureAwait(false);
}
public async Task Disconnect()
{
await HubConnection.StopAsync().ConfigureAwait(false);
}
public async Task SendMessage(Message message)
{
await HubConnection.InvokeAsync("SendMessage", message).ConfigureAwait(false);
}
}
-登录后应用程序启动时连接到集线器:
public MainPage()
{
InitializeComponent();
MasterBehavior = MasterBehavior.Popover;
//should be home page
MenuPages.Add((int)MenuItemType.Home, (NavigationPage)Detail);
HubService.Connect().ConfigureAwait(true);
}
-注销时关闭连接
-发送消息时调用 SendMessage 方法:
await HubService.SendMessage(message).ConfigureAwait(true);
OutGoingText = string.Empty;
Messages.Add(message);
现在的问题是当我发送消息并到达:
public async Task SendMessage(Message message)
{
await HubConnection.InvokeAsync("SendMessage", message).ConfigureAwait(false);
}
抛出这个:
System.InvalidOperationException: 'The 'InvokeCoreAsync' method cannot be called if the connection is not active'
已经尝试使用 HubService.Connect().Wait() 但应用程序处于循环状态
谁能帮我解决这个问题?? @Nick Kovalsky...
此致
我找到问题了!
问题是调用 "HubService.Connect().ConfigureAwait(true);",它是构造函数中的异步方法,因此无法等待。
public MainPage()
{
InitializeComponent();
MasterBehavior = MasterBehavior.Popover;
//should be home page
MenuPages.Add((int)MenuItemType.Home, (NavigationPage)Detail);
HubService.Connect().ConfigureAwait(true);
}
解决方法是将调用 "HubService.Connect().ConfigureAwait(true);" 移动到 App.xaml.cs 并将其放入 "OnStart()" 方法中:
protected override async void OnStart()
{
await HubService.Connect().ConfigureAwait(true);
}
谢谢大家!
我创建了一个带有聊天和 API 的 Xamarin 应用程序来存储它的数据,移动应用程序每 3 分钟向 api 请求聊天消息。
我决定按照评论中的建议使用 SignalR:
-将其添加到我的 CongifureService 中,如图所示:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<HostelContext>(opt =>
opt.UseSqlServer(Configuration.GetConnectionString("HostelContext")));
services.AddCors();
services.AddControllers();
services.AddAuthentication("BasicAuthentication")
.AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", null);
services.AddScoped<IUsersService, UsersService>();
services.AddScoped<IConversationsService, ConversationsService>();
services.AddScoped<IMessagesService, MessagesService>();
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "HostelApi", Version = "v1" });
});
services.AddSignalR();
}
- 添加端点进行配置,如图所示:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<ChatHub>("/chatHub");
});
-将 Class 添加到我的 api 项目中名为 Hub
的新文件夹中-这是中心 class:
//[Authorize]
public class ChatHub : Hub
{
public async Task SendMessage(Message message)
{
//await Clients.All.SendAsync("ReceiveMessage", message);
await Clients.All.SendAsync("ReceiveMessage" + message.ConversationId, message);
//await Clients.Users(destinationUserIdList).SendAsync("ReceiveMessage" + message.ConversationId, message);
}
}
在我的 Xamarin 应用中:
- 添加的集线器服务:
-这是集线器服务 Class:
class HubService : IHubService
{
public HubConnection HubConnection { get; }
public HubService()
{
HubConnection = new HubConnectionBuilder()
.WithUrl($"https://10.0.2.2:5001/chatHub")
.Build();
}
public async Task Connect()
{
await HubConnection.StartAsync().ConfigureAwait(false);
}
public async Task Disconnect()
{
await HubConnection.StopAsync().ConfigureAwait(false);
}
public async Task SendMessage(Message message)
{
await HubConnection.InvokeAsync("SendMessage", message).ConfigureAwait(false);
}
}
-登录后应用程序启动时连接到集线器:
public MainPage()
{
InitializeComponent();
MasterBehavior = MasterBehavior.Popover;
//should be home page
MenuPages.Add((int)MenuItemType.Home, (NavigationPage)Detail);
HubService.Connect().ConfigureAwait(true);
}
-注销时关闭连接
-发送消息时调用 SendMessage 方法:
await HubService.SendMessage(message).ConfigureAwait(true);
OutGoingText = string.Empty;
Messages.Add(message);
现在的问题是当我发送消息并到达:
public async Task SendMessage(Message message)
{
await HubConnection.InvokeAsync("SendMessage", message).ConfigureAwait(false);
}
抛出这个:
System.InvalidOperationException: 'The 'InvokeCoreAsync' method cannot be called if the connection is not active'
已经尝试使用 HubService.Connect().Wait() 但应用程序处于循环状态
谁能帮我解决这个问题?? @Nick Kovalsky...
此致
我找到问题了!
问题是调用 "HubService.Connect().ConfigureAwait(true);",它是构造函数中的异步方法,因此无法等待。
public MainPage()
{
InitializeComponent();
MasterBehavior = MasterBehavior.Popover;
//should be home page
MenuPages.Add((int)MenuItemType.Home, (NavigationPage)Detail);
HubService.Connect().ConfigureAwait(true);
}
解决方法是将调用 "HubService.Connect().ConfigureAwait(true);" 移动到 App.xaml.cs 并将其放入 "OnStart()" 方法中:
protected override async void OnStart()
{
await HubService.Connect().ConfigureAwait(true);
}
谢谢大家!