SignalR连续消息 [英] SignalR continuous messaging

查看:211
本文介绍了SignalR连续消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这需要统计一个Web项目/网页上的日志,以从外部SOAP服务进行更新。我已决定采取与此方法是使用signalR,由于具有code,将执行服务方法,并把结果返回给所有连接的客户端。这code将连续执行,服务电话之间的延迟。

I have a web project which requires stats/logs on a web page to be updated from an external soap service. The approach I have decided to take with this is to use signalR, by having code that would execute a service method and return the results to all connected clients. This code will be continuously executed, with a delay between service calls.

我无法把所有的作品一起,可能是因为我不知道这里的​​一切应该去!这里是什么我迄今所做的粗略细分

I am having trouble putting all of the pieces together, probably because I am not sure where everything should go! Here is a rough breakdown at what I have done so far

class Data { ... }

interface IDataService
{
    Task GetDataAsync(TimeSpan interval, CancellationToken cancellationToken, Action<Data> callback);
}

class DataService : IDataService
{
    private readonly ExternalService _externalService;

    public async Task GetDataAsync(TimeSpan interval, CancellationToken cancellationToken, Action<Data> callback)
    {
         while (!cancellationToken.IsCancellationRequested)
         {
              var data = await this._externalService.GetData();
              callback(data);

              await Task.Delay(interval).ConfigureAwait(false);
         }
    }
}

所以上述的是,从外部服务获得的数据,并执行一个回呼的逻辑。至于signalR,我做的唯一的事情如下:

So above is the logic that gets the data from the external service, and executes a callback. As for signalR, the only thing I have done is as follows

public class DataHub : Hub
{
    private readonly IDataService _service;

    public DataHub(IDataService service)
    {
        this._service = service;
    }

    public async Task GetData()
    {
        var tenSeconds = new TimeSpan(0, 0, 10);
        var token = new CancellationToken();
        await _service.GetDataAsync(tenSeconds, token, d =>
        {
             // signal all connected clients
        });
    }
}

的GetData()客户端连接(如果它尚未运行)方法可以被调用,当有连接到没有更多的客户令牌可以被取消轮毂。

The GetData() method can be called when clients connect (if it isn't already running) and the token can be cancelled when there are no more clients connected to the hub.

(潜在的)问题:


  1. SignalR集线器不是单身是什么人?我认为需要时创建,当再没有必要(请求处理)处理。在这种情况下,我将有的GetData 方法的多个实例上运行(除非我做DataService类单身/注射作为一个单身)。

  2. 集线器不觉得这样做的正确的地方。集线器应该像一个MVC /网络API控制器可以治疗吗?因此,一个请求时,中心处理它,请求完成。故事结束。

  3. 另一种方式做,这将是中枢传递到DataService的。然后,它可以调用客户端。但我真的不希望被绕过IHubContext对象。我想保持服务尽可能地简单。

  4. 请问一个ASP.NET后台任务更合适吗?

  1. SignalR hubs are not singletons are they? I assume they are created when needed and disposed when not needed anymore (request has finished). In which case I will have multiple instances of the GetData method running (unless I make the DataService class a singleton/injected as a singleton).
  2. A hub doesn't feel like the right place to do this. A hub should be treated like an MVC/Web Api controller? So a request comes in, hub handles it, request is finished. End of story.
  3. Another way to do this would be to pass the hub into the dataservice. And then it can call the clients. But I don't really want to be passing around IHubContext objects. I want to keep the service as simple as possible.
  4. Would an ASP.NET background task be more appropriate here?

将不胜感激,如果有人可以点我到正确的/最好的方法!

Would be grateful if someone can point me to the right/best approach!

推荐答案

我设法通过使用IRegisteredObject接口在System.Web.Hosting命名空间来解决这个问题。所以我的计划任务是:

I have managed to solve this issue by using the IRegisteredObject interface in the System.Web.Hosting namespace. So my scheduled task is:

public class DataTask : IRegisteredObject
{
     private readonly IGlobalData _global;
     private readonly IDataService _service;
     private readonly IHubContext _hub;

     private Timer _timer;

     public DataTask(IGlobalData global, IDataService service, IHubContext hub)
     {
          this._global = global;
          this._service = service;
          this._hub = hub;

          var interval = new TimeSpan(0, 0, 10);
          this._timer = new Timer(updateClients, null, TimeSpan.Zero, interval);

          // register this task with asp.net
          HostingEnvironment.RegisterObject(this);
     }

     public void Stop(bool immediate)
     {
          _timer.Dispose();

          HostingEnvironment.UnregisterObject(this);
     }

     private async void updateClients(object state)
     {
          var result = await this._service.GetData();
          // call the hub
          this._hub.Clients.All.updateData(result);
     }
}

我也有不少的问题!但是,这是因为我使用了signalR自定义依赖解析器(问题是客户端js函数没有被从该任务调用)。一旦得到解决,一切正常。

I did have quite a few issues! But this was due to the custom dependency resolver I was using for signalR (the problem was the client js function was not being called from this task). Once that was resolved, everything works as expected.

这篇关于SignalR连续消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆