如何将 SignalR 添加到 .NET Core Windows 服务?

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

我可以找到将其添加到 MVC 的教程,甚至从 2014 年开始,就有一篇文章解释如何将其添加到 .NET 4.7 windows 服务。

然而,对于 .NET Core 3.1 Windows 服务,我只是不知道如何做到这一点。

大多数教程似乎都围绕 Windows 服务中不存在的 Startup.cs 文件。 这是我可以从 Microsoft 找到的最新教程,但它使用 Web 应用程序而不是 Windows 服务。

Windows 服务使用以下代码运行:

var builder = new HostBuilder() .ConfigureServices((hostContext, services) => { services.AddHostedService<MyWindowsService>(); });


我认为 SignalR 需要在此处设置。

我发现了一些你可以做到的证据

WebApp.Start("http://localhost:8080");

 但这是 OWIN。我找到的示例(上面的示例的旧版本)有一个 Startup 类,但没有指示如何调用该类。它需要一个 
IAppBuilder
 并且有一个方法可以添加 SignalR。但是 IAppBuilder 似乎不是 .NET Core,我也找不到任何类型的 SignalR 方法。

我想知道是否有人可以指出我正确的方向?

c# .net-core windows-services signalr
2个回答
6
投票
对于想要开发在 Windows 服务中运行的自托管 ASPNETCore SignalR 中心的人们,这是我的准系统代码。 (

免责声明:我是 ASPNET Core 的新手,我不知道这种方法是否会被更有知识的人认可。)神奇之处在于 .UseStartup<Startup>();

 调用。

  1. 使用 VS 2019

    “Worker Service”C# 模板创建一个新的服务项目。

  2. 编辑

    服务的 .csproj 文件并插入以下行:

    <ItemGroup> <FrameworkReference Include="Microsoft.aspNetCore.App" /> </ItemGroup>
    
    
  3. 创建一个

    Startup

    类:

    using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Text; namespace My.SignalRCore.Service { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddSignalR(); services.AddHostedService<Worker>(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); // pre-requisite for app.UseEndpoints() app.UseEndpoints(endpoints => { string url = $"/ServerHub"; endpoints.MapHub<MyHub>(url); }); } } }
    
    
  4. 创建一个

    MyHub : Hub

    类:

    using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; namespace My.SignalRCore.Service { public class MyHub : Hub { public ILogger<Worker> _logger = null; public MyHub(ILogger<Worker> logger) { _logger = logger; //_logger.LogInformation($"{DateTimeOffset.Now} MyHub.Constructor()"); } public async Task ProcessClientMessage(string user, string message) { // process an incoming message from a connected client _logger.LogInformation($"{DateTime.Now.ToString("hh:mm:ss.fff")} MyHub.ProcessClientMessage({user}, {message})"); } } }
    
    
  5. 修改

    Program

     类以使用 
    UseStartup
     调用:

    using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; using System; namespace My.SignalRCore.Service { 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://*:12457"); }); } }
    
    
  6. hub

     类中添加 
    Worker
     参考(如果需要):

    using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace My.SignalRCore.Service { public class Worker : BackgroundService { private readonly ILogger<Worker> _logger; private readonly IHubContext<MyHub> _signalRHub; public Worker(ILogger<Worker> logger, IHubContext<MyHub> signalRHub) { _logger = logger; _signalRHub = signalRHub; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { await Task.Delay(15000, stoppingToken); _logger.LogInformation($"{DateTime.Now.ToString("hh:mm:ss.fff")} Sending ping to all clients"); await _signalRHub.Clients.All.SendAsync("ReceiveMessage", "Server", "ping"); } } } }
    
    
服务器代码就是这样。我尚未将其安装为服务,但它可以作为控制台应用程序运行。 在非开发计算机上,您可能需要安装 APSNET CORE 3.1 运行时,可在此处获取:

https://dotnet.microsoft.com/download/dotnet/3.1

对于客户:

  1. 安装NuGet包:

    Microsoft.AspNetCore.SignalR.Client

    
    

  2. 按照以下方式创建客户端类(

    注意:此处的重新连接代码不起作用):

    using Microsoft.AspNetCore.SignalR.Client; using System; using System.Threading.Tasks; namespace My.SignalRCoreClientLib { public class SignalRCoreClientLib { public EventHandler<string> MessageEvent; private HubConnection _connection; public async Task Connect(string serverIp, int port) { if (_connection == null) { _connection = new HubConnectionBuilder() .WithUrl($"http://{serverIp}:{port}/ServerHub") .Build(); _connection.Closed += async (error) => { await Task.Delay(new Random().Next(0, 5) * 1000); await _connection.StartAsync(); }; _connection.On<string, string>("ReceiveMessage", (user, message) => { string fullMessage = $"{user}: {message}"; MessageEvent?.Invoke(this, fullMessage); }); } try { await _connection.StartAsync(); } catch (Exception ex) { MessageEvent?.Invoke(this, $"{ex.Message}; base Exception: {ex.GetBaseException().Message}"); await Task.Delay(new Random().Next(0, 5) * 1000); await Connect(serverIp, port); } } public async Task SendMessage(string user, string message) { try { await _connection.InvokeAsync("ProcessClientMessage", user, message); } catch (Exception ex) { MessageEvent?.Invoke(this, ex.Message); } } } }
    
    
就是这样。希望这对您有帮助!


2
投票
SignalR 服务器端需要一个能够正常接收 Web 请求的服务器,Kestrel 或 IIS。因此,您需要一个 Web 应用程序,您仍然可以将托管服务添加到您的 Web 应用程序,甚至有一个示例显示带有 SignalR 和托管服务的 Web 应用程序:

https://learn.microsoft.com/aspnet/core/signalr/后台服务?view=aspnetcore-5.0

© www.soinside.com 2019 - 2024. All rights reserved.