【问题标题】:My AspnetCore application does not receive publications from a .net core console application via SignalR我的 AspnetCore 应用程序没有通过 SignalR 接收来自 .net 核心控制台应用程序的发布
【发布时间】:2021-03-07 14:45:10
【问题描述】:

我的 AspnetCore 应用程序没有通过 SignalR 接收来自 .net 核心控制台应用程序的发布

我有一个包含 SignalR Hub 的 aspnet core 2.1 Web 应用程序。

我需要制作一个 .net core 2.1 控制台应用程序,将信息发送到我的网络系统上的集线器。

我在这里做了一个开发,但是当我运行我的控制台应用程序时,没有出现异常,但是我的网络应用程序没有收到信息。

看看我到目前为止做了什么。

Aspnet 核心 2.1

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDistributedMemoryCache();
            services.AddSession();
            services.Configure<CookiePolicyOptions>(options =>
            {
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddSignalR();
            services.AddMvc(
                    config => {
                    var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
                    config.Filters.Add(new AuthorizeFilter(policy));
                }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddAuthentication(options =>
            {
                options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            }).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
                options =>
                {
                    options.ExpireTimeSpan = TimeSpan.FromDays(1);
                    options.LoginPath = "/Home/Login";
                    options.LogoutPath = "/Usuario/Logout";
                    options.SlidingExpiration = true;
                });
            //provedor postgresql
            services.AddEntityFrameworkNpgsql()
             .AddDbContext<MesContext>(options => 
             options.UseNpgsql(Configuration.GetConnectionString("MesContext")));

            services.AddScoped<SeedingService>();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, SeedingService seedingService)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }
            seedingService.Seed();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseAuthentication();
            app.UseSession();
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
            
            app.UseSignalR(routes =>
            {
                routes.MapHub<MesHub>("/MesHub");
            });
        }
    }

查看索引

//teste
    // ATUALIZA LISTAGEM
    connection.on("teste", function (sucesso, msg) {
        if (sucesso) {
            console.log(msg);
        }
    });

集线器

public class MesHub : Hub
    {
        public static ConcurrentDictionary<string, List<string>> ConnectedUsers = new ConcurrentDictionary<string, List<string>>();

        
        public void SendAsync(string message)
        {
            // Call the addMessage method on all clients
             Clients.All.SendAsync("teste", true, message);
        }

        public override Task OnConnectedAsync()
        {
            string name = Context.User.Identity.Name;

            Groups.AddToGroupAsync(Context.ConnectionId, name);

            return base.OnConnectedAsync();
        }
    }

控制台应用

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Teste Renan!");

            var url = "https://localhost:44323/meshub";

            var connection = new HubConnectionBuilder()
                .WithUrl($"{url}")
                .WithAutomaticReconnect() //I don't think this is totally required, but can't hurt either
                .Build();

            var t = connection.StartAsync();
            Console.WriteLine("conected!");
            //Wait for the connection to complete
            t.Wait();

            Console.WriteLine(connection.State);
            

            //connection.SendAsync("SendAsync", "renan");

            connection.InvokeAsync<string>("SendAsync", "HELLO World ").ContinueWith(task => {
                if (task.IsFaulted)
                {
                    Console.WriteLine("There was an error calling send: {0}",
                                      task.Exception.GetBaseException());
                }
                else
                {
                    Console.WriteLine(task.Result);
                }
            });
            Console.WriteLine("enviado!"); 
}
}

在控制台应用程序中,我添加了 Microsoft.aspnetCore.SignalR.Client 包

Signalr 在 aspnet 核心网络系统中运行良好,因为它不会从外部接收信息。

我忘记了什么?我做错了什么?

【问题讨论】:

  • 如果您调试 hub 方法,当您从控制台客户端应用程序调用它时,它是否达到预期的方法?
  • 不是。到目前为止,我已经找到了导致问题的原因,在我的集线器中,我有一个 OnConnectedAsync 方法,其中通知了组的名称,因为没有应用程序控制台,我没有设置组,因此它没有连接。
  • in my Hub I have an OnConnectedAsync method where the name of the group is informed嗨@Renan,请检查我的新更新。

标签: asp.net-core .net-core signalr


【解决方案1】:

我定义了相同的集线器方法并进行了测试以从控制台客户端调用它,它按预期工作。

此外,我使用我的 SignalR 控制台客户端应用程序对其进行了测试,它也运行良好。如果可能,您可以对其进行测试并检查它是否适合您。

static void Main(string[] args)
{
    Console.WriteLine("Client App Starts...");

    Program p = new Program();
    p.Myfunc().Wait();

    Console.ReadLine();

}

public async Task Myfunc()
{
    HubConnection connection = new HubConnectionBuilder()
        .WithUrl("https://localhost:44323/meshub") 
        .Build();

    connection.Closed += async (error) =>
    {
        await Task.Delay(new Random().Next(0, 5) * 1000);
        await connection.StartAsync();
    };


    await connection.StartAsync();

    try
    {
        await connection.InvokeAsync("SendAsync", "HELLO World ");
        //await connection.InvokeAsync("SendMessage", "console app", "test mes");
    }
    catch (Exception ex)
    {

        Console.WriteLine(ex.Message);
    }
       
}

测试结果

更新:

在我的集线器中,我有一个 OnConnectedAsync 方法,其中通知组的名称

您可以尝试更新OnConnectedAsync方法如下,然后检查您的SignalR控制台客户端应用程序是否可以连接到集线器并与Web客户端通信良好。

public override async Task OnConnectedAsync()
{
    string name = Context.User.Identity.Name;

    if (name != null)
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, name);
    }

    await base.OnConnectedAsync();
}

【讨论】:

  • 在您的中心类中,“OnConnectedAsync”方法是否与我的代码匹配?
  • 会不会导致OnConnectedAsync方法出现异常?
  • 这是否有效。字符串名称 = Context.User.Identity.Name; if (name == null) { name = "控制台"; }await Groups.AddToGroupAsync(Context.ConnectionId, name);您的 if 将无法正常工作。你怎么看?
  • 如果 name 为 null,await Groups.AddToGroupAsync(Context.ConnectionId, name); 会抛出异常,这似乎是问题的原因。
  • 如何为应用程序的控制台端定义名称?今天我在我之前写的 if 中定义。
猜你喜欢
  • 2022-08-20
  • 2018-05-14
  • 1970-01-01
  • 2019-09-26
  • 2021-05-13
  • 2020-07-17
  • 2020-07-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多