从SignalR集线器调用Web-Api

时间:2018-11-21 15:26:56

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

我正在创建带有集成SignalR集线器的WebApi服务器。为简单起见,我使用的是在List上运行的Controller。

  [Route("api/[controller]")]
  [ApiController]
  public class ValuesController : ControllerBase
  {

    public static List<string> Source { get; set; } = new List<string>();
    public static int counter = 0;

    private IHubContext<ValuesHub, IValuesClient> hubContext;

    public ValuesController(IHubContext<ValuesHub, IValuesClient> hub)
    {
      Source.Add("bla" + counter);
      counter++;
      Source.Add("bla" + counter);
      counter++;
      this.hubContext = hub;
    }

    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
      return Source;
    }

    // GET api/values/x
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
      return Source[id];
    }

    // POST api/values
    [HttpPost]
    public void Post([FromBody] string value)
    {
      Source.Add(value);
    }

    // PUT api/values/x
    [HttpPut("{id}")]
    public void Put(int id, [FromBody] string value)
    {
      Source[id] = value;
    }

    // DELETE api/values/x
    [HttpDelete("{id}")]
    public void Delete(int id)
    {
      var item = Source[id];
      Source.Remove(item);
      Console.WriteLine("Outgoing message!");
      hubContext.Clients.All.ReceiveMessage("Message incoming", "Blaaaaa");
    }
  }
}

“我的中心”还没有执行任何特殊操作:

  public interface IValuesClient
  {
    Task ReceiveMessage(string value, string message);
    Task ReceiveMessage(string message);
  }

  public class ValuesHub : Hub<IValuesClient>
  {

    // private static ValuesController ctrl = Glo

    public override async Task OnConnectedAsync()
    {
      await Groups.AddToGroupAsync(Context.ConnectionId, "Users");
      Console.WriteLine("Client connected - Client-Id: {0}", Context.ConnectionId);
      await base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception exception)
    {
      await Groups.RemoveFromGroupAsync(Context.ConnectionId, "Users");
      Console.WriteLine("Client disconnected - Client-Id: {0}", Context.ConnectionId);
      Console.WriteLine("Disconnection due to: {0}", exception);
      await base.OnDisconnectedAsync(exception);
    }

    public async Task MessageToAll(string user, string message)
    {
      Console.WriteLine("SendMessage - User: {0} - Message: {1}", user, message);
      await Clients.All.ReceiveMessage(user, message);
    }

    public async Task MessageToCaller(string message)
    {
      Console.WriteLine("SendMessageToCaller: {0}", message);
      await Clients.Caller.ReceiveMessage(message);
    }
  }
}

为了简单起见,我将不详细说明为什么要实现此目的,但是我希望服务器在检测到断开连接后等待一定时间,然后删除相应的值。假设我只想删除Source列表中的第一个元素。

我如何从OnDisconnectedAsync函数内部访问相应的控制器功能?

我想到的一个想法是在集线器内部创建一个HttpClient,并通过调用e使集线器在此处充当客户端。 G。 DELETE: http://localhost:5000/api/values/0。不过,我必须承认这听起来像是一种非常可怕的方法。

1 个答案:

答案 0 :(得分:1)

因此,如果我了解您的问题是您要从集线器访问控制器上的方法,则该问题是否存在?

如果是这种情况-在我看来,您有一个基本的设计缺陷。我将创建一个处理您控制器正在执行的所有操作的服务,然后将该服务直接注入到集线器中。然后,您可以直接在替代中心中使用该服务,并在列表上进行操作。如果不清楚,我可以举个例子。

   public class ValuesHub : Hub<IValuesClient>
    {
   IListService _listService; 
 public ValuesHub (IListService listService)
    {
        _listService = listService;
    }

public override async Task OnConnectedAsync()
{
  await Groups.AddToGroupAsync(Context.ConnectionId, "Users");
  Console.WriteLine("Client connected - Client-Id: {0}", Context.ConnectionId);
  await base.OnConnectedAsync();
}

public override async Task OnDisconnectedAsync(Exception exception)
{
  await Groups.RemoveFromGroupAsync(Context.ConnectionId, "Users");
  Console.WriteLine("Client disconnected - Client-Id: {0}", Context.ConnectionId);
  Console.WriteLine("Disconnection due to: {0}", exception);
   //Call your methods here.
  _listService.RemoveFirstElement();
  await base.OnDisconnectedAsync(exception);
}

public async Task MessageToAll(string user, string message)
{
  Console.WriteLine("SendMessage - User: {0} - Message: {1}", user, message);
  await Clients.All.ReceiveMessage(user, message);
}

public async Task MessageToCaller(string message)
{
  Console.WriteLine("SendMessageToCaller: {0}", message);
  await Clients.Caller.ReceiveMessage(message);
}
   }
 }

这就是您的中心-请参见下面的服务示例

  public class ListService : IListService
   {
    public void RemoveFirstElement()
    {
        //Delete Your Element here
    }
}

public interface IListService
{
    void RemoveFirstElement();
}

然后是您的startup.cs

 services.AddSingleton<IListService,ListService>();