如何让自托管 signalR 服务器作为 NetCore 控制台应用程序运行

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

我想使用 .NetCore 在控制台应用程序中创建 SignalR 自托管服务器。

我对 Web 开发和 .Net Core 完全陌生,但想使用 SignalR 作为基于实时 Web 的协议。不需要网页,所以我想要一个控制台应用程序。

我已经成功测试了下面的 .Net Framework 示例,并希望使用 .Net Core 3.1 复制它,以便它可以在 Linux 上运行。但是我找不到任何合适的例子。

using System;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Hosting;
using Owin;
using Microsoft.Owin.Cors;

namespace SignalRSelfHost
{
    class Program
    {
        static void Main(string[] args)
        {
            // This will *ONLY* bind to localhost, if you want to bind to all addresses
            // use http://*:8080 to bind to all addresses. 
            // See http://msdn.microsoft.com/library/system.net.httplistener.aspx 
            // for more information.
            string url = "http://localhost:8088";
            using (WebApp.Start<Startup>(url))
            {
                Console.WriteLine("Server running on {0}", url);
                Console.ReadLine();
            }
        }
    }
    class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);
            app.MapSignalR();
        }
    }
    public class MyHub : Hub
    {
        public void Send(string name, string message)
        {
            Clients.All.addMessage(name, message);
            Clients.All.addMessage(name, "World");
        }
    }
}

在尝试使用 Owin 创建服务器控制台应用程序时,我有以下代码并且可以编译,但是在运行程序时抱怨没有注册服务器服务。有人可以建议添加什么来拥有没有网页的网络服务器吗?我复制的示例指定了 UseKestrel() 但我认为这是针对网页的,所以我认为我需要其他东西。

using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace OwinConsole
{
    public class Startup
    {
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseOwin(pipeline =>
            {
                pipeline(next => OwinHello);
            });
        }

        public Task OwinHello(IDictionary<string, object> environment)
        {
            string responseText = "Hello World via OWIN";
            byte[] responseBytes = Encoding.UTF8.GetBytes(responseText);

            // OWIN Environment Keys: http://owin.org/spec/spec/owin-1.0.0.html
            var responseStream = (Stream)environment["owin.ResponseBody"];
            var responseHeaders = (IDictionary<string, string[]>)environment["owin.ResponseHeaders"];

            responseHeaders["Content-Length"] = new string[] { responseBytes.Length.ToString(CultureInfo.InvariantCulture) };
            responseHeaders["Content-Type"] = new string[] { "text/plain" };

            return responseStream.WriteAsync(responseBytes, 0, responseBytes.Length);
        }
    }
}
using System.IO;
using Microsoft.AspNetCore.Hosting;

namespace OwinConsole
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }
    }
}

谢谢。

asp.net-core signalr asp.net-core-3.1 self-hosting
2个回答
11
投票

对于那些想要在 .NET 6 中实现这一目标的人:

要创建一个简单的服务器作为控制台应用程序,您必须创建一个新的空 ASP.NET Core 项目。在 .NET 6 中,您不再需要“startup.cs”。您只需更改“Program.cs”中的一些内容即可配置 SignalR。

程序.cs

var builder = WebApplication.CreateBuilder(args);

//builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

//app.MapRazorPages();
app.MapHub<ChatHub>("/chatHub");

app.Run();

添加中心

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        Console.WriteLine("Received message, sending back echo");
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

客户端(控制台应用程序)

例如:

using Microsoft.AspNetCore.SignalR.Client;

namespace Client
{
    public class Program
    {
        private static HubConnection _connection;
        public static async Task Main(string[] args)
        {            
            _connection = new HubConnectionBuilder()
                .WithUrl("https://localhost:7116/chatHub")                
                .Build();

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

            await ConnectAsync();
            
            bool stop = false;
            while (!stop)
            {
                Console.WriteLine("Press any key to send message to server and receive echo");
                Console.ReadKey();
                Send("testuser", "msg");
                Console.WriteLine("Press q to quit or anything else to resume");
                var key = Console.ReadLine();
                if (key == "q") stop = true;
            }                        
        }

        private static async Task ConnectAsync()
        {
            _connection.On<string, string>("ReceiveMessage", (user, message) =>
            {
                Console.WriteLine("Received message");
                Console.WriteLine($"user: {user}");
                Console.WriteLine($"message: {message}");
            });
            try
            {
                await _connection.StartAsync();
            }
            catch(Exception e)
            {
                Console.WriteLine("Exception: {0}", e);
            }
        }

        private static async void Send(string user, string msg)
        {
            try
            {
                await _connection.InvokeAsync("SendMessage", user, msg);
            }
            catch (Exception e)
            {
                Console.WriteLine($"Exception: {e}");
            }
        }
    }
}

客户端将连接到服务器,之后循环中您可以通过按任意键向服务器发送消息,服务器将向您发送相同的消息。

在“launchSettings.json”(服务器)中,您可以找到 applicaitonUrl


0
投票

正如诺亚提到的,我的解决方案基于

[https://learn.microsoft.com/en-us/aspnet/core/tutorials/signalr?view=aspnetcore-5.0&tabs=visual-studio]

而是构建为引用 Microsoft.AspNetCore.App (2.2.8) 的控制台应用程序。

聊天中心

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace SignalRServer
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

启动

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

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

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddRazorPages();
            services.AddSignalR();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                //endpoints.MapRazorPages();
                endpoints.MapHub<ChatHub>("/chatHub");
            });
        }
    }
}

节目

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace SignalRServer
{

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    webBuilder.UseUrls("http://localhost:2803");
                });
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.