调用SignalR Hub不适用于Asp.Net Core Web API

时间:2018-08-22 13:38:22

标签: c# asp.net-core .net-core signalr asp.net-core-webapi

我是SignalR的新手。我正在尝试设置一个Asp.Net Core WebAPI,以便其他客户端可以使用SignalR连接到它并获取实时数据。 我的Hub类是:

public class TimeHub : Hub
{
    public async Task UpdateTime(string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", message);
    }
}

我有一个中继课程,如下所示:

public class TimeRelay : ITimeRelay
{
    private readonly IHubContext<TimeHub> _timeHubContext;

    public TimeRelay(IHubContext<TimeHub> context)
    {

        _timeHubContext = context;
        Task.Factory.StartNew(async () =>
        {
            while (true)
            {
                await context.Clients.All.SendAsync("UpdateTime", DateTime.Now.ToShortDateString());
                Thread.Sleep(2000);
            }
        });
    }
}

启动类:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    services.AddSignalR();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseDeveloperExceptionPage();

    app.UseHttpsRedirection();

    app.UseSignalR((x) =>
    {
        x.MapHub<TimeHub>("/timeHub");
    });
    app.UseMvc();
}

客户端是一个控制台应用程序,代码为:

class Program
{    
    static Action<string> OnReceivedAction = OnReceived;

    static void Main(string[] args)
    {
        Connect();
        Console.ReadLine();
    }

    private static async void Connect()
    {
        var hubConnectionBuilder = new HubConnectionBuilder();

        var hubConnection = hubConnectionBuilder.WithUrl("http://localhost:60211/timeHub").Build();

        await hubConnection.StartAsync();

        var on = hubConnection.On("ReceiveMessage", OnReceivedAction);

        Console.ReadLine();    
        on.Dispose();
        await hubConnection.StopAsync();
    }

    static void OnReceived(string message)
    {
        System.Console.WriteLine($"{message}");
    }
}

我尝试调试该应用程序。客户端成功连接到TimeHub。客户端建立连接后,Clients.All中的连接数从0更改为1。但是,当执行await context.Clients.All.SendAsync("UpdateTime", DateTime.Now.ToShortDateString());时,UpdateTime中的TimeHub函数没有得到执行,客户端也没有得到任何消息。

我尝试在类"UpdateTime"中的"SendMessage"中使用"ReceiveMessage"Clients.All.SendAsyncTimeRelay作为方法。没事。有人可以指出我对此的错误。

2 个答案:

答案 0 :(得分:1)

对于Clients,如果没有客户端连接到服务器,则它将为null。为了同时启动Asp.Net Core SignalRConsole AppClients可能为null,因为可以在Console App连接signalR服务器之前调用Index

尝试以下步骤:

  1. 更改TimeHub

    public class TimeHub: Hub
    {
    public async Task UpdateTime(string message)
    {
        if (Clients != null)
        {
            await Clients.All.SendAsync("ReceiveMessage", message);
        }
    }
    }
    
  2. 注册TimeHub

     services.AddSingleton<TimeHub>();  
    
  3. 控制器

     public class HomeController : Controller
    {
    private readonly TimeHub _timeHub;
    public HomeController(TimeHub timeHub)
    {
        _timeHub = timeHub;
    }
    public IActionResult Index()
    {
        Task.Factory.StartNew(async () =>
        {
            while (true)
            {
                try
                {
                    await _timeHub.UpdateTime(DateTime.Now.ToShortDateString());
                    Thread.Sleep(2000);
                }
                catch (Exception ex)
                {
    
                }
            }
        });
        return View();
    }
    

答案 1 :(得分:0)

我让它工作了,以为我会在这里回答。感谢@TaoZhou的提示。

我的错误是从服务器发送“ UpdateTime”并在客户端等待“ ReceiveMessage”。

理想情况下,代码应如下所示:

SignalR服务器:
await context.Clients.All.SendAsync("UpdateTime", DateTime.Now.ToShortDateString());

SignalR客户:
var on = hubConnection.On("UpdateTime", OnReceivedAction);

在这种情况下,从服务器发送的任何消息都会立即在客户端收到。
请参考问题中提供的代码以获取更多信息。